c语言——大文件拷贝

48 篇文章 4 订阅

c语言——大文件拷贝

按【字符】读取复制

本文代码在deepin(Linux系统)下编译与测试


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include<sys/types.h>
#include <sys/stat.h>
//10M大小
#define MAXSIZE 1024*1024*10

//  有点问题,会多一个字符
//  gcc -o mycp1 mycp1.c
// ./mycp1 ccc.mp4 ccc1.mp4
//-rw-r--r-- 1 zzyy zzyy 29141800 5月  10 22:14 ccc1.mp4
//-rwxrw-rw- 1 zzyy zzyy 29141799 12月 16 13:58 ccc.mp4

int main(int argc, char* argv[])
{
	unsigned int start_time = time(NULL);
	if (argc < 3)
	{
		printf("缺少参数\n");
		return -1;
	}
	//mycp    wow.2.mp4 wow.3.mp4
	//argv[0] argv[1]   arr[2]
	FILE* fp1 = fopen(argv[1], "rb");
	FILE* fp2 = fopen(argv[2], "wb");
	if (!fp1 || !fp2)
	{
		printf("操作文件失败\n");
		return -2;
	}

	char ch;
	while (feof(fp1)==0)
	{
         ch=fgetc(fp1);
		fputc(ch, fp2);
	}
    

	fclose(fp1);
	fclose(fp2);


	unsigned int end_time = time(NULL);

	printf("花费时间:%d(s)\n", end_time - start_time);

	return 0;

}

按【块】读取复制

这个也有点问题,


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include<sys/types.h>
#include <sys/stat.h>
//10M大小
#define MAXSIZE 1024*1024*10

//  有点问题,会多字符
//  gcc -o mycp mycp.c
// ./mycp ccc.mp4 ccc1.mp4
//-rw-r--r-- 1 zzyy zzyy 29142016 5月  10 22:45 ccc1.mp4
//-rwxrw-rw- 1 zzyy zzyy 29141799 12月 16 13:58 ccc.mp4


int main(int argc, char* argv[])
{
	unsigned int start_time = time(NULL);
	if (argc < 3)
	{
		printf("缺少参数\n");
		return -1;
	}
	//mycp    wow.2.mp4 wow.3.mp4
	//argv[0] argv[1]   arr[2]
	FILE* fp1 = fopen(argv[1], "rb");
	FILE* fp2 = fopen(argv[2], "wb");
	if (!fp1 || !fp2)
	{
		printf("操作文件失败\n");
		return -2;
	}

	char ch[1024];
	while (!feof(fp1))
	{
		memset(ch, 0, 1024);
		fread(ch, 1024, 1,fp1);
		fwrite(ch,1024 ,1,fp2);
	}
    

	fclose(fp1);
	fclose(fp2);


	unsigned int end_time = time(NULL);

	printf("花费时间:%d(s)\n", end_time - start_time);

	return 0;

}

问题思考

拷贝的文件明显有问题,比原文件大了一些。
我们再看一下fread函数。

#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:以数据块的方式从文件中读取内容
参数:
	ptr:存放读取出来数据的内存空间
	size: size_t 为 unsigned int类型,此参数指定读取文件内容的块数据大小
	nmemb:读取文件的块数,读取文件数据总大小为:size * nmemb
	stream:已经打开的文件指针
返回值:
	成功:实际成功读取到内容的块数,如果此值比nmemb小,但大于0,说明读到文件的结尾。
	失败:0

我们能不能,把size设置为1,nmemb设置为1024,也就是

原来:
每次读=块数据大小  1024 * 1次
现在:
每次读=块数据大小  1 * 1024

按【块】读取复制【改进】

	while (!feof(fp1))
	{
		memset(ch, 0, 1024);
		int  len = fread(ch, 1, 1024,fp1);
		fwrite(ch,len ,1,fp2);
	}

测试

$ gcc -o mycp mycp.c 
$ ./mycp ccc.mp4 ccc1.mp4 
$ ls -all
29141799 510 23:02 ccc1.mp4
29141799 1216 13:58 ccc.mp4

测试通过。

按【块】读取复制【快速版】

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
//10M大小
#define MAXSIZE 1024*1024*10


int main(int argc, char* argv[])
{
	unsigned int start_time = time(NULL);
	if (argc < 3)
	{
		printf("缺少参数\n");
		return -1;
	}
    printf("%s\n",argv[1]);
    printf("%s\n",argv[2]);
	//mycp    wow.2.mp4 wow.3.mp4
	//argv[0] argv[1]   arr[2]
	FILE* fp1 = fopen(argv[1], "r");//windows要改成rb
	FILE* fp2 = fopen(argv[2], "w");//windows要改成wb
	if (!fp1 || !fp2)
	{
		printf("操作文件失败\n");
		return -2;
	}

	//获取文件属性
	struct stat st = { 0 };
	//获取源文件
	stat(argv[1], &st);
    printf("FileSize=%d\n",st.st_size);
    //return 0;
    printf("获取源文件信息成功\n");
	char* ch;
	int maxSize = 0;
	if (st.st_size < MAXSIZE)
	{
        printf("maxSize1=%d\n",st.st_size);
		maxSize = st.st_size;
		ch = (char*)malloc(sizeof(char) * st.st_size);
	}
	else
	{
        printf("maxSize2=%d\n",MAXSIZE);
		maxSize = MAXSIZE;
		ch = (char*)malloc(sizeof(char) * MAXSIZE);
	}

	while (!feof(fp1))
	{
		memset(ch,0,maxSize);
		int len = fread(ch, 1, maxSize, fp1);//123
		fwrite(ch, 1, len, fp2);
	}

	fclose(fp1);
	fclose(fp2);

	free(ch);
	unsigned int end_time = time(NULL);

	printf("花费时间:%d(s)\n", end_time - start_time);

	return 0;

}

按【块】读取复制【快速版】结构体指针

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include<sys/types.h>
#include <sys/stat.h>
//10M大小
#define MAXSIZE 1024*1024*10


int main()
{
	unsigned int start_time = time(NULL);

	//mycp    wow.2.mp4 wow.3.mp4
	//argv[0] argv[1]   arr[2]
	FILE* fp1 = fopen("C:\\Users\\MagicBook\\Desktop\\vshello\\ccc.mp4", "rb");//windows要改成rb
	FILE* fp2 = fopen("C:\\Users\\MagicBook\\Desktop\\vshello\\ccc1.mp4", "wb");//windows要改成wb
	if (!fp1 || !fp2)
	{
		printf("操作文件失败\n");
		return -2;
	}

	//获取文件属性
	struct stat *st = (struct stat*) malloc(sizeof(struct stat));
	//获取源文件
	stat("C:\\Users\\MagicBook\\Desktop\\vshello\\ccc.mp4", st);
	char* ch;
	int maxSize = 0;
	if (st->st_size < MAXSIZE)
	{
		maxSize = st->st_size;
		ch = (char*)malloc(sizeof(char) * st->st_size);
	}
	else
	{
		maxSize = MAXSIZE;
		ch = (char*)malloc(sizeof(char) * MAXSIZE);
	}
	while (!feof(fp1))
	{
		memset(ch, 0, maxSize);
		int len = fread(ch, 1, maxSize, fp1);//123
		fwrite(ch, 1, len, fp2);
	}


	fclose(fp1);
	fclose(fp2);

	free(st);
	free(ch);
	unsigned int end_time = time(NULL);

	printf("花费时间:%d(s)\n", end_time - start_time);

	return 0;

}

fread的一些问题

调试发现,fread在windows下不能读完整个文件。需要在fopen处优化一下代码。
fread不能读完整个文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值