我有两个功能。一种复制文本文件,使用"r"
和"w"
模式进行读写,另一种复制二进制文件,使用"rb"
和 "wb
"模式。
但是如果我要使用这些功能,我必须首先确定我要复制的文件是文本文件还是二进制文件。我想要一个解决方案,允许我在不知道文件性质的情况下成功复制文件。处理这个问题的单个函数。有任何想法吗?
P.S:我注意到 ctrl + c
copy 比我的函数更快,因此也欢迎提供提高函数速度的提示。
#include <stdio.h>
void copyfile_txt(const char *inputfile, const char *outputfile);
void copyfile_bin(const char *inputfile, const char *outputfile);
int main(void)
{
copyfile_txt("file_input.txt", "file_output.txt");
copyfile_bin("ubuntu-14.04.3-desktop-amd64.iso", "Ubuntu.iso");
return 0;
}
long GetFileSize(FILE *fp)
{
fseek(fp, 0L, SEEK_END);
long sz = ftell(fp);
fseek(fp, 0L, SEEK_SET);
return sz;
}
void copyfile_txt(const char *inputfile, const char *outputfile)
{
static FILE *fp_I;
static FILE *fp_O;
fp_I = fopen(inputfile, "r");
if (!fp_I) {
perror(inputfile);
return;
}
fp_O = fopen(outputfile, "w");
if (!fp_O) {
fclose(fp_I);
perror(outputfile);
return;
}
static int c;
while ((c = getc(fp_I)) != EOF) {
putc(c, fp_O);
}
fclose(fp_I);
fclose(fp_O);
}
void copyfile_bin(const char *inputfile, const char *outputfile)
{
static FILE *fp_I;
static FILE *fp_O;
fp_I = fopen(inputfile, "rb");
if (!fp_I) {
perror(inputfile);
return;
}
fp_O = fopen(outputfile, "wb");
if (!fp_O) {
fclose(fp_I);
perror(outputfile);
return;
}
static int c;
static long n;
static long sz;
n = 0;
sz = GetFileSize(fp_I);
while (n++ < sz) {
c = getc(fp_I);
putc(c, fp_O);
}
fclose(fp_I);
fclose(fp_O);
}
最佳答案
您不需要对文本文件进行特例,将所有文件复制为二进制文件。这是大多数文件复制实用程序所做的。
但是请注意,您的二进制文件复制功能有问题:
无需计算文件大小,复制直到得到
EOF
是正确的,并且允许您复制大于LONG_MAX
的文件。不需要静态变量:使用
static
变量会使您的函数在多个线程中使用时失败。返回完成代码会很有用。
这是一个更简单的版本:
int copyfile_bin(const char *inputfile, const char *outputfile) {
FILE *fp_I;
FILE *fp_O;
fp_I = fopen(inputfile, "rb");
if (!fp_I) {
perror(inputfile);
return -1;
}
fp_O = fopen(outputfile, "wb");
if (!fp_O) {
fclose(fp_I);
perror(outputfile);
return -1;
}
int c;
while ((c = getc(fp_I)) != EOF) {
putc(c, fp_O);
}
fclose(fp_I);
if (fclose(fp_O) != 0) {
perror(outputfile);
return -1;
}
return 0;
}
为了提高速度,您可以使用 setvbuf()
或使用 fread()
和 fwrite()
来增加缓冲区大小分配缓冲区。
为了更快的内部循环,使用这个:
size_t nr, size = 1024 * 1024;
void *buffer = malloc(size);
if (buffer != NULL) {
while ((nr = fread(buffer, 1, size, fp_I)) > 0) {
if (fwrite(buffer, 1, nr, fp_O) != nr) {
fprintf(stderr, "write error: ");
perror(outputfile);
free(buffer);
fclose(fp_I);
fclose(fp_O);
return -1;
}
}
if (ferror(fp_I)) {
fprintf(stderr, "read error: ");
perror(inputfile);
free(buffer);
fclose(fp_I);
fclose(fp_O);
return -1;
}
free(buffer);
} else {
/* use the regular getc/putc loop */
int c;
while ((c = getc(fp_I)) != EOF) {
putc(c, fp_O);
}
}
关于使用一种功能复制文本和二进制文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39191266/