2

I'm trying to use ifstream/ofstream to read/write but for some reason, the data gets corrupted along the way. Heres the read/write methods and the test:

void FileWrite(const char* FilePath, std::vector<char> &data) { std::ofstream os (FilePath); int len = data.size(); os.write(reinterpret_cast<char*>(&len), 4); os.write(&(data[0]), len); os.close(); } std::vector<char> FileRead(const char* FilePath) { std::ifstream is(FilePath); int len; is.read(reinterpret_cast<char*>(&len), 4); std::vector<char> ret(len); is.read(&(ret[0]), len); is.close(); return ret; } void test() { std::vector<char> sample(1024 * 1024); for (int i = 0; i < 1024 * 1024; i++) { sample[i] = rand() % 256; } FileWrite("C:\\test\\sample", sample); auto sample2 = FileRead("C:\\test\\sample"); int err = 0; for (int i = 0; i < sample.size(); i++) { if (sample[i] != sample2[i]) err++; } std::cout << err << "\n"; int a; std::cin >> a; } 

It writes the length correctly, reads it correctly and starts reading the data correctly but at some point(depending on input, usually at around the 1000'th byte) it goes wrong and everything to follow is wrong. Why is that?

3
  • to write an array at this maner, you must convert it to char[] or char* or using loop and ostream& operator << and istream& operator >> Commented Oct 11, 2015 at 13:31
  • Compiled this with g++ and it works well (ran it 10 times). What compiler are you using? I'm not very confident with your write/read operation using first vector item reference. Did you try to use for/while and read/fill the vector item per item? Commented Oct 11, 2015 at 13:32
  • 1
    In (reinterpret_cast<char*>(&len), 4) do not assume the size of len is 4. Instead use sizeof(len). Commented Oct 11, 2015 at 13:33

1 Answer 1

2

for starter, you should open the file stream for binary read and write :

std::ofstream os (FilePath,std::ios::binary); 

(edit: assuming char really means "signed char")
Do notice that regular char can hold up to CHAR_MAX/2 value, which is 127. If the random number is bigger - the result will wrap around, resulting negative value. the stream will try to write this character as a text character, which is invalid value to write. binary format should at least fix this problem.

Also, you shouldn't close the stream yourself here, the destructor does it for you.

Two more simple points:
1) &(data[0]) should be just &data[0], the () are redundant
2) try keep the same convention. you write upper-camel-case for FilePath variable, but lower-camel-case for all the other variables.

Sign up to request clarification or add additional context in comments.

4 Comments

do notice that regular char can hold up to CHAR_MAX/2 value, which is 127. That does not have to be true. a char can either be signed or unsigned. that is implementation defined.
@NathanOliver alright, I learn something new every day. I wasn't aware that char can be unsigend by implementation. I added a line
oh yeah, i keep mixing up char and byte(as its defined in .net)... shouldn't matter in this case though
the binary mode did, yes :D

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.