Byu*_*ang 2 c filesize fwrite fread
我正在 Visual Studio 中编写程序。\n我使用fread和复制了一个文件fwrite。\n输出文件大小比输入文件大。\n你能解释一下原因吗?
#define _CRT_SECURE_NO_WARNINGS\n#include <stdio.h>\n#include <stdlib.h>\n#include <memory.h>\n\nint main()\n{\n char *buffer;\n int fsize;\n\n FILE *fp = fopen("test.txt", "r");\n FILE *ofp = fopen("out.txt", "w");\n fseek(fp, 0, SEEK_END);\n fsize = ftell(fp);\n\n buffer = (char *)malloc(fsize);\n memset(buffer, 0, fsize); // buffer\xeb\xa5\xbc 0\xec\x9c\xbc\xeb\xa1\x9c \xec\xb4\x88\xea\xb8\xb0\xed\x99\x94\n\n fseek(fp, 0, SEEK_SET);\n fread(buffer, fsize, 1, fp);\n\n fwrite(buffer, fsize, 1, ofp);\n\n fclose(fp);\n fclose(ofp);\n free(buffer);\n}\nRun Code Online (Sandbox Code Playgroud)\n
您以文本模式打开文件,在使用 Visual Studio 的 Windows 操作系统上,这涉及到重要的翻译阶段,包括行尾转换。如果您的文件具有二进制内容,例如可执行文件、图像和文档文件,则行尾转换会将“\n”字节替换为 CR LF 对,从而增加输出大小。
"rb"您可以通过使用和模式字符串以二进制模式打开文件来避免此问题"wb"。
另请注意,流必须以二进制模式打开才能ftell()可靠地返回文件大小,假设文件支持查找并且不大于LONG_MAXWindows 上的 2GB。对于 POSIX 系统,使用stat从操作系统检索文件大小是更好的方法。一次复制一个文件块也更可靠:它适用于不支持查找的流,并允许复制大于可用内存的文件。
这是带有错误检查的修改版本:
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
const char *inputfile = "test.txt";
const char *outputfile = "out.txt";
FILE *fp = fopen(inputfile, "rb");
if (fp == NULL) {
fprintf(stderr, "cannot open %s: %s\n", inputfile, strerror(errno);
return 1;
}
FILE *ofp = fopen(outputfile, "wb");
if (ofp == NULL) {
fprintf(stderr, "cannot open %s: %s\n", outputfile, strerror(errno);
return 1;
}
if (fseek(fp, 0, SEEK_END)) {
fprintf(stderr, "%s: cannot seek to the end of file: %s\n",
inputfile, strerror(errno);
return 1;
}
size_t fsize = ftell(fp);
char *buffer = calloc(fsize, 1);
if (buffer == NULL) {
fprintf(stderr, "cannot allocate %zu bytes: %s\n",
fsize, strerror(errno);
return 1;
}
rewind(fp);
size_t nread = fread(buffer, fsize, 1, fp);
if (nread != fsize) {
fprintf(stderr, "%s: read %zu bytes, file size is %zu bytes\n".
inputfile, nread, fsize);
}
size_t nwritten = fwrite(buffer, nread, 1, ofp);
if (nwritten != nread) {
fprintf(stderr, "%s: wrote %zu bytes, write size is %zu bytes\n".
outputfile, nwritten, nread);
}
fclose(fp);
if (fclose(ofp)) {
fprintf(stderr, "%s: error closing file: %s\n".
outputfile, strerror(errno));
}
free(buffer);
return 0;
}
Run Code Online (Sandbox Code Playgroud)