0

我正在将几个较小的文件编译成一个大文件。

我试图让每个小文件都以一定的粒度开始,在我的例子中是 4096。

因此,我正在填补每个文件之间的空白。

为此,我使用了

//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();
}

但是 iCheck 返回

 iCheck = 3503

我预计它是0。

有人看到我的错误吗?

4

1 回答 1

0

iStart % 4096是自前一个 4k 边界以来的字节数。您想要直到下一个 4k 边界的字节数,即(4096 - iStart % 4096) % 4096.

您可以用 替换外部模运算符if,因为它的唯一目的是更正40960保持所有其他值不变。如果 4096 的值是质数,那将是值得的。但由于 4096 实际上是 4096,它是 2 的幂,编译器将使用位掩码进行模运算(至少,假设 iStart 是无符号的),所以上面的表达式可能会更有效。

顺便说一句,您可以将文件 fseek 到末尾以外的位置,并且该文件将被 NUL 字节填充。所以你实际上并没有自己做所有这些工作:

fseek() 函数应允许将文件位置指示符设置在文件中现有数据的末尾之外。如果稍后在此点写入数据,则后续读取间隙中的数据应返回值为 0 的字节,直到数据实际写入间隙。 (Posix 2008)

于 2013-10-12T22:11:45.323 回答