Target: There is text file (on HDD) containing integers divided with some kind of delimiter.
Example:
5245
234224
6534
1234
I need to read them into STL container.
int main(int argc, char * argv[]) {
using namespace std;
// 1. prepare the file stream
string fileName;
if (argc > 1)
fileName = argv[1];
else {
cout << "Provide the filename to read from: ";
cin >> fileName;
}
unique_ptr<ifstream, ifstream_deleter<ifstream>> ptrToStream(new ifstream(fileName, ios::out));
if (!ptrToStream->good()) {
cerr << "Error opening file " << fileName << endl;
return -1;
}
// 2. value by value reading will be too slow on large data so buffer data
typedef unsigned int values_type;
const int BUFFER_SIZE(4); // 4 is for testing purposes. 16MB or larger in real life
vector<values_type> numbersBuffer(BUFFER_SIZE);
numbersBuffer.insert(numbersBuffer.begin(), istream_iterator<values_type>(*ptrToStream), istream_iterator<values_type>());
// ...
The main drawback of this code is how can I handle the issue when file size is extremely large, so I cannot store all of it’s contents in memory ?
I also do not want to use push_back as it is non efficient in comparison to interval insert.
So, the question is: how can I read not more than BUFFER_SIZE elements from the file effectively using STL?
The approach to limit reading from input iterators is to create a wrapper which counts the number of elements processed so far and whose end iterator compares to this number. Doing this generically isn’t quite trivial, doing it specifically for
std::istream_iterator<T>shouldn’t be too hard. That said, I think the easiest way to do it is this:I realize that you don’t want to
push_back()because it is allegedly slow. However, compared to the I/O operation I doubt that you’ll be able to measure the small overhead, especially with typical implementation of the I/O library.Just to round things off with an example of a wrapped iterator: below is an example how a counting wrapper for
std::istream_iterator<T>could look like. There are many different ways this could be done, this is just one of them.