前置基础
函数一: fread
函数声明:
- buf , 从p文件中读取的数据
- sizeof(void) ,每次从p中读取数据的大小
- len ,每次从p中读取数据的个数
- p , 打开的文件地址
解释:
sizeof( void ) 和 len 是搭配使用的,它们的作用就是令临时空间使用完:
返回值:
fread 的返回值是每次从p中读取的数据的个数,也就是len 的值。
函数二:fwrite
函数声明:
- buf , 临时空间,每次从buf中读取数据,然后写入p中
- sizeof(void) ,每次往p中写入数据块的大小
- nums ,每次往p中写入的数据
- p , 打开的文件地址
解释:
fwrite的使用于fread是相互映照的。
返回值:
返回每次写入的次数。
基本思路:
- 打开要读取的文件a
- 打开要写入的文件b
- 读取a ,存放到临时的空间中
- 读取临时空间的数据,写入b
- 关闭a
- 关闭b
- 如果使用的是堆空间,释放临时空间
代码实现:
mycopy.c :
解析:
上述代码主要通过一个1kB的空间来实现缓存区,通过缓存区把一个文件的数据读出来,然后把数据写入要复制的文件内。
运行结果:
通过运行得到以下下文件
代码失误:
上述代码虽然可以把文件给复制下来,但还不能完美的复制下来,test2.mp4 尾数是144,test1.mp4 尾数是383,明显比原文件小。
错误原因:
- 每次都要往文件中写入1024个,最后一次会读取到文件末尾,跳出循环,不够1024会舍弃数据。
测试代码:
创建一个a.txt
文件有5个字节的空间
代码
当最后读取空间不够时,会跳出循环。
改进后代码:
改进后的代码,最后读出不够3个字节,“abcde” ,只读出了2个字节,然后写入到文件b.txt中。
测试结果:
可以看到b.txt文件比原文件又大了一个字节。
- 所以我们找到了第二个错误,写入字节没控制好。
解决方法:通过设置读文件字节的返回值,来设置写文件的次数。
代码实现:
res 是 fread 读出1个字节的次数,然后把它设为写入1个字节的次数,这样就不会复制失败任何一个字节。
代码提升:
当我们发现我们可以通过设置临时空间来实现文件的复制的时候,我们会非常高兴,但当一个文件非常小的时候,我们设置了一个非常大的临时空间,这就浪费了内存;当文件非常大的时候,我们设计了一个非常小的临时空间,我们函数的循环的时间久会变长,也是非常难受,那有没有一种非常好的方法,每次用多少内存就开辟多少的临时空间呢?
当然是有的!
我们可以通过使用stat函数来获取文件的字节大小,根据文件的大小开辟对应的内存空间,并合理的规划文件的拷贝次数,从而达到文件被拷贝的目的。
代码实现:
通过上述代码,我们实现了每次拷贝不超过10KB的文件一次拷贝完的操作,如果文件大于10KB,就只申请10KB的内存空间,实现了动态开辟内存来存储临时数据。
测试结果
完结!
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/2397.html