我正在用C创建一个存档程序,我想要它保存我提供的文件,列出并提取它们。
我有很多问题,因为我使用文本文件进行保存,如果我想处理音乐或照片等二进制文件,它不是最佳选择,因为当我提取它们时,它们没有正确执行(它们已损坏)。
为了解决这个问题,我想创建一个二进制存档文件。
文件写入代码(提取时)如下:
void scriviFile(const char * arrivo) //scrive i file creati in precedenza
{
FILE * partenza;
FILE * target;
int c;
int spazio = 'a';
int i = 0;
int pos;
char * path;
path = collegaSlash(getcwd(NULL, 0), nome);
partenza = fopen(path, "rb");
fseek(partenza, inizio, SEEK_SET);
target = fopen(arrivo, "wb"); //apro il file
if (target) { //se è aperto
while ((c = fgetc(partenza)) != EOF && ftell(partenza)<=fine-10) { //e il carattere preso non eccede la fine del file
fputc(c, target);
fputc(c, stdout);
pos = ftell(partenza);
if(pos==fine)
{
break;
}
//scrivo lo stesso carattere in out (file in uscita)
} //
fclose(target); //chiudo il file
fclose(partenza);
}
else
{
printf("errore di scrittura del file \n");
}
}
由于我需要正确提取二进制文件,我可以使用上面编写的代码,还是必须使用fgetc()
和{{1更改所有fputc()
和fread()
函数}}?
由于
答案 0 :(得分:8)
您正在使用fgetc()
和fputc()
,因为您可以从手册页说明中看到这些功能:
fgetc()从流中读取下一个字符,并将其作为无符号字符串转换为int,或者在文件末尾或错误时返回EOF。
fputc()将字符c(强制转换为无符号字符串)写入流。
C中的字符由标准定义为始终正好是1字节(8位),这意味着当您在文件上使用fxxxc()
时,您将获得1个字节(恰好是文本文件中的字符)。
如果逐字节提取并重建二进制文件,则会得到完全相同的内容。所以不,在二进制文件类型上使用fgetc()
和fputc()
没有问题。您总是可以通过一个简单的示例程序向自己证明这一点......例如:
int main()
{
FILE * fptr = fopen("small_pic.jpg", "rb"); // open existing binary picture
char buffer[10000] = {0}; // the pic is 6kb or so, so 10k bytes will hold it
FILE * fptr2 = fopen("new_small_pic.jpg", "wb"); // open a new binary file
// for our copy of the pic
unsigned long fileLen;
unsigned long counter;
fseek(fptr, 0, SEEK_END);
fileLen=ftell(fptr); // get the exact size of the pic
fseek(fptr, 0, SEEK_SET);
for(counter=0; counter<fileLen; counter++)
fputc(fgetc(fptr),fptr2); // read each byte of the small_pic.jpg and make
// a new pic from it
fclose(fptr);
fclose(fptr2);
return 0;
}
最终结果:我们有两个完全相同的图像,因为fgetc()
和fputc()
可用于二进制文件。
答案 1 :(得分:0)
我正在用C创建一个归档程序,我希望它能保存文件i 提供,列出和提取它们。我有很多问题,因为我使用过 用于保存的文本文件,如果我愿意,它不是最佳选择 处理二进制文件,如音乐或照片,因为当我提取 它们,它们没有正确执行(它们已损坏)。为了 要解决这个问题,我想创建一个二进制存档文件。
- SNIP -
由于我需要正确提取二进制文件,我可以使用代码i 如上所述,或者我必须更改所有fgetc()和fputc()函数 用fread()和fwrite()?
在二进制模式下工作时,您可以使用上面编写的代码。它与fgetc
,fputc
,fread
和fwrite
无关。在文本模式下工作时此函数无法正常工作的原因是ftell
不能保证对fseek
以外的任何其他内容有用,因此代码{{1}在文本模式下打开文件时,不是特别合适。通过重构代码,您可以删除ftell(partenza)<=fine-10
并使用大于4GB的文件...但这不应该是重构此代码的唯一原因。