# Bizarre, inconsistent behaviour in file I/O

This topic is 3736 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I've made a 2D skeletal animation animation editor for my current project. However, there's a problem: occasionally, an animation file will be saved but then appear "corrupted" when I attempt to load it again. The data will load correctly up until a certain point, where fread figures that it's hit the end of file and refuses to load any more data. I've done the math, and the file I'm loading is exactly the size that I'd expect it to be. Additionally, the issue only occurs sporadically... it appears almost completely random whether or not a file will be saved with such a bug. The only thing I can imagine that would cause this is that I'm accidentally writing some kind of end of file marker into my animation files, yet I haven't been able to find any information on the subject yet. Here's my code:
bool Animation::LoadFromFile(string &filename)
{
//Open file
FILE *file = fopen(filename.c_str(), "r");
if(!file)
{
hge->System_Log("Couldn't load file: %s", filename.c_str());
return false;
}

ClearExisting();

int numKeyFrames = 0;
fread(&numKeyFrames, sizeof(int), 1, file);
int numBonesPerFrame = 0;
fread(&numBonesPerFrame, sizeof(int), 1, file);

for(int i = 0; i < numKeyFrames; i++)
{
float pos;
fread(&pos, sizeof(float), 1, file);

KeyFrame *temp = new KeyFrame;
temp->position = pos;

for(int j = 0; j < numBonesPerFrame; j++)
{
BoneState *boneState = new BoneState;
temp->boneStates.push_back(boneState);
fread(&boneState->angle, sizeof(float), 1, file);
fread(&boneState->lengthFactor, sizeof(float), 1, file);
}

keyFrames.push_back(temp);
}

//Close file
if(fclose(file))
{
hge->System_Log("Couldn't close file after loading: %s", filename.c_str());
return false;
}
return true;
}

bool Animation::SaveToFile(string &filename)
{
//Open file
FILE *file = fopen(filename.c_str(), "w");
if(!file)
{
hge->System_Log("Couldn't save file: %s", filename.c_str());
return false;
}

int numKeyFrames = (int)keyFrames.size();
fwrite(&numKeyFrames, sizeof(int), 1, file);
int numBonesPerFrame = (int)keyFrames[0]->boneStates.size();
fwrite(&numBonesPerFrame, sizeof(int), 1, file);

for(int i = 0; i < numKeyFrames; i++)
{
fwrite(&keyFrames->position, sizeof(float), 1, file);
for(int j = 0; j < numBonesPerFrame; j++)
{
fwrite(&keyFrames->boneStates[j]->angle, sizeof(float), 1, file);
fwrite(&keyFrames->boneStates[j]->lengthFactor, sizeof(float), 1, file);
}
}

//Close file
if(fclose(file))
{
hge->System_Log("Couldn't close file after saving: %s", filename.c_str());
return false;
}
return true;
}


Does anyone have any insight as to how to fix this? The problem can be worked around, because not all files seem to be affected (and affected ones can be sometimes fixed by redoing the work that was lost), but it is a huge pain in the ass to lose 15 frames of an animation for no apparent reason. Thanks!  By the way, I've spent a large amount of time debugging and I can guarantee that ferror isn't flagging anything in either function. When the errors occur, it's always in the load function and feof is always returning a nonzero value too early.

##### Share on other sites
fopen(filename.c_str(), "rb");

I won't comment on not using std::fstream.

##### Share on other sites
try it on a different hard drive?

##### Share on other sites
I know, I know. Actually, I tried rewriting the code using fstream, but strangely enough it gave me the same problems, just with different files becoming unreadable. I'll chalk that up to inexperience, though.

Thanks, I didn't know there was a binary flag for that! I'll let you know if it fixes it.

##### Share on other sites
Nope, didn't work. It's operating the same way I saw it misbehave when I was using fstream with ios::binary... most files are opening correctly, some of the ones that weren't now do what they're supposed to, but some files that previously worked are incompatible!

I haven't checked file contents, but if it's anything like when I was using fstream, I'm getting junk values past as certain point in the file.

I'm obviously missing something here... is extra data being written into my files when I don't write them in binary mode? Does binary mode have any caveats I need to watch for? This entire thing is driving me nuts...

##### Share on other sites
Alright, I think I fixed it. I loaded all my existing animations in text mode and saved them in binary to convert them, and then loading them in binary worked fine.

Most files stays the same, actually, but a couple of them changed enough for the SVN to pick up on it. So I have a question: does writing to a file in text mode automatically put carriage returns after X number of bytes, or somesuch? I've never seen that in any sort of documentation, but that'd definitely explain my results.

##### Share on other sites
Text mode (the default in almost all I/O libraries) converts newlines (LF aka Line Feed, "\n", ASCII 10) to local-OS newlines (Unix: LF, Mac: CR (Carriage Return, ASCII 13), Windows CR+LF (one after the other)) when written to file. Reading in text mode converts local-OS newlines in the file to LF in memory.

Using binary mode results in no such translation.

Ah, thank you.

1. 1
2. 2
Rutin
20
3. 3
4. 4
frob
13
5. 5

• 9
• 13
• 10
• 9
• 17
• ### Forum Statistics

• Total Topics
632601
• Total Posts
3007356

×

## Important Information

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!