12

So, here's my problem: I want to make a program that reads chunks of data from a file. Let's say, 1024 bytes per chunk. So I read the first 1024 bytes, perform various operations and then open the next 1024 bytes, without reading the old data. The program should keep reading data untile the EOF is reached.

I'm currently using this code:

std::fstream fin("C:\\file.txt");

vector<char> buffer (1024,0); //reads only the first 1024 bytes
fin.read(&buffer[0], buffer.size());

But how can I read the next 1024 bytes? I was thinking by using a for loop, but I don't really know how. I'm totally a noob in C++, so if anyone can help me out, that would be great. Thanks!

jndok
  • 859
  • 3
  • 12
  • 28
  • http://www.cplusplus.com/reference/fstream/fstream/rdbuf/ – user2485710 Jan 03 '14 at 19:50
  • 3
    Yes, a loop is the way to go. Also, you should use `fin.gcount()` to figure out who much data was actually read. Also, if you are only reading, you should use `std::ifstream` (and in case you want to read binary data rather than text, you should open the file with `std::ios_base::binary`). – Dietmar Kühl Jan 03 '14 at 19:50

3 Answers3

14

You can do this with a loop:

std::ifstream fin("C:\\file.txt", std::ifstream::binary);
std::vector<char> buffer (1024,0); //reads only the first 1024 bytes

while(!fin.eof()) {
    fin.read(buffer.data(), buffer.size())
    std::streamsize s=fin.gcount();
    ///do with buffer
}

##EDITED

http://en.cppreference.com/w/cpp/io/basic_istream/read

orangepips
  • 9,601
  • 6
  • 29
  • 56
111111
  • 14,528
  • 6
  • 38
  • 58
9

Accepted answer doesn't work for me - it doesn't read last partial chunk. This does:

void readFile(std::istream &input, UncompressedHandler &handler) {
    std::vector<char> buffer (1024,0); //reads only 1024 bytes at a time
    while (!input.eof()) {
        input.read(buffer.data(), buffer.size());
        std::streamsize dataSize = input.gcount();
        handler({buffer.begin(), buffer.begin() + dataSize});
    }
}

Here UncompressedHandler accepts std::string, so I use constructor from two iterators.

MateuszL
  • 2,212
  • 19
  • 31
  • Because on last (not full) read, istream goes eof and so evaluates to false and doesn't enter while body – MateuszL Mar 19 '20 at 13:42
  • Yes I get it now. Thanks. For others, check return value of https://en.cppreference.com/w/cpp/io/basic_istream/read (return the stream itself `*this`), and its bool overloading method https://en.cppreference.com/w/cpp/io/basic_ios/operator_bool . (`1) Returns a null pointer if fail() returns true`). When the stream reaches its end, `fail()` returns `true`. – Rick Mar 19 '20 at 14:00
0

I think you missed up that there is a pointer points to the last place you've visit in the file , so that when you read for the second time you will not start from the first , but from the last point you've visit . Have a look to this code

std::ifstream fin("C:\\file.txt");
char buffer[1024]; //I prefer array more than vector for such implementation

fin.read(buffer,sizeof(buffer));//first read get the first 1024 byte

fin.read(buffer,sizeof(buffer));//second read get the second 1024 byte

so that how you may think about this concept .

Mostafa 36a2
  • 149
  • 15