Reputation: 878
I have to read some binary file in blocks of 8 bytes and then send those blocks by tcp socket. Can I use C++ iterator for this task? Like:
FileIterator file("name_file.bin");
for(iter = file.begin(); iter != file.end(); iter++) {
sendTcp(iter);
}
Class FileIterator
has to return some struct which will be sent.
In constructor of FileIterator
I open binary file and read it. Then I create dinamic array and write in it file's content. And in each step iterator I have to read next block from array and write it in struct and return.
Upvotes: 2
Views: 2676
Reputation: 33952
I see this as an X-Y problem. Yes, it can be done with an iterator, but iterators aren't the best fit solution for this job. Using an iterator for this is an interesting educational experience, but going old school solves this problem with almost zero fuss and much easier error resolution.
#include <iostream>
#include <fstream>
// simple 8 byte struct
struct EightByteStruct
{
uint32_t a;
uint32_t b;
};
// quick hack send routine. Added capacity for some simple error checking.
bool sendTcp(EightByteStruct & test)
{
bool rval = false;
// send test. Set rval true if success
return rval;
}
//main event: read file into struct, write struct to socket
int main()
{
std::ifstream in("filename", std::ios::binary);
EightByteStruct test;
while (in.read((char*)&test, sizeof(test)))
{ // will not enter if sizeof(test) bytes not read from file
if (sendTcp(test))
{
// handle send error
}
}
// test here for any file error conditions you wish to have special handling
}
Upvotes: 2
Reputation: 694
Yes you can!
You can use fstream with istream_iterator, like so:
auto f = std::ifstream("lol.bin", std::ios::binary | std::ios::in);
f.exceptions(std::ios::badbit);
for (auto start = std::istream_iterator<char>{ f }, end = std::istream_iterator<char>{}; start != end; ++start)
{
...
}
Edit: I haven't notice you asked for 8 bytes block. The way you can solve it is like this:
First define an operator>> for example:
struct My8Bytes {
char bytes[8];
};
std::istream& operator>>(std::istream& s, My8Bytes& bytes) {
s.read(bytes.bytes, sizeof(bytes.bytes));
return s;
}
and than use the the iterator the same way as before, only now with your specific type:
for (auto start = std::istream_iterator<My8Bytes>{ f }, end = std::istream_iterator<My8Bytes>{}; start != end; ++start)
{
...
}
Upvotes: 7