0

I am compiling several smaller files into one big file.

I am trying to make it so that each small file begins at a certain granularity, in my case 4096.

Therefore I am filling the gap between each file.

To do that I used

//Have a look at the current file size
unsigned long iStart=ftell(outfile);

//Calculate how many bytes we have to add to fill the gap to fulfill the granularity
unsigned long iBytesToWrite=iStart % 4096;

//write some empty bytes to fill the gap
vector <unsigned char>nBytes;
nBytes.resize(iBytesToWrite+1);
fwrite(&nBytes[0],iBytesToWrite,1,outfile);

//Now have a look at the file size again
iStart=ftell(outfile);

//And check granularity
unsigned long iCheck=iStart % 4096;
if (iCheck!=0)
{
    DebugBreak();
}

However iCheck returns

 iCheck = 3503

I expected it to be 0.

Does anybody see my mistake?

tmighty
  • 10,734
  • 21
  • 104
  • 218

1 Answers1

0

iStart % 4096 is the number of bytes since the previous 4k-boundary. You want the number of bytes until the next 4k-boundary, which is (4096 - iStart % 4096) % 4096.

You could replace the outer modulo operator with an if, since it's only purpose is to correct 4096 to 0 and leave all the other values untouched. That would be worthwhile if the value of 4096 were, say, a prime. But since 4096 is actually 4096, which is a power of 2, the compiler will do the modulo operation with a bit mask (at least, provided that iStart is unsigned), so the above expression will probably be more efficient.

By the way, you're allowed to fseek a file to a position beyond the end, and the file will be filled with NUL bytes. So you actually don't have do all that work yourself:

The fseek() function shall allow the file-position indicator to be set beyond the end of existing data in the file. If data is later written at this point, subsequent reads of data in the gap shall return bytes with the value 0 until data is actually written into the gap. (Posix 2008)

rici
  • 234,347
  • 28
  • 237
  • 341