在C中试用和真正的简单文件复制代码?

在C中试用和真正的简单文件复制代码?,第1张

概述这看起来像一个简单的问题,但我没有发现任何类似的东西. 由于C中没有文件复制功能,我们必须自己实现文件复制,但是我不喜欢重新发明轮子,即使是这样的微不足道的东西,所以我想问云: >使用fopen()/ fread()/ fwrite()),您建议使用什么代码进行文件复制? >使用open()/ read()/ write(),您建议使用什么代码进行文件复制? 这个代码应该是可移植的(windows 这看起来像一个简单的问题,但我没有发现任何类似的东西.

由于C中没有文件复制功能,我们必须自己实现文件复制,但是我不喜欢重新发明轮子,即使是这样的微不足道的东西,所以我想问云:

>使用fopen()/ fread()/ fwrite()),您建议使用什么代码进行文件复制?

>使用open()/ read()/ write(),您建议使用什么代码进行文件复制?

这个代码应该是可移植的(windows / mac / linux / bsd / qnx / younameit),稳定的,时间测试的,快速的,内存高效的等等.进入特定系统的内部来挤压一些更多的性能是受欢迎的(如获取文件系统集群大小) .

这似乎是一个琐碎的问题,但是例如,CP命令的源代码不是10行C代码.

解决方法 就实际的I / O而言,我将数据从一个流复制到另一个流程的代码写在百万次以上,就像这样.在成功时返回0,或者在错误时设置了errno(在这种情况下可能会复制任何数量的字节).

请注意,对于复制常规文件,您可以跳过EAGAIN的东西,因为常规文件总是阻止I / O.但是不可避免地,如果你写这个代码,有人会使用它在其他类型的文件描述符,所以认为它是一个免费的.

有一个文件特定的GNU cp优化,我没有在这里烦恼,对于0个字节的长块而不是写你只是通过寻求结束扩展输出文件.

voID block(int fd,int event) {    pollfd topoll;    topoll.fd = fd;    topoll.events = event;    poll(&topoll,1,-1);    // no need to check errors - if the stream is bust then the    // next read/write will tell us}int copy_data_buffer(int fdin,int fdout,voID *buf,size_t bufsize) {    for(;;) {       voID *pos;       // read data to buffer       ssize_t bytestowrite = read(fdin,buf,bufsize);       if (bytestowrite == 0) break; // end of input       if (bytestowrite == -1) {           if (errno == EINTR) continue; // signal handled           if (errno == EAGAIN) {               block(fdin,PolliN);               continue;           }           return -1; // error       }       // write data from buffer       pos = buf;       while (bytestowrite > 0) {           ssize_t bytes_written = write(fdout,pos,bytestowrite);           if (bytes_written == -1) {               if (errno == EINTR) continue; // signal handled               if (errno == EAGAIN) {                   block(fdout,PolLOUT);                   continue;               }               return -1; // error           }           bytestowrite -= bytes_written;           pos += bytes_written;       }    }    return 0; // success}// Default value. I think it will get close to maximum speed on most// systems,short of using mmap etc. But porters / integrators// might want to set it smaller,if the system is very memory// constrained and they don't want this routine to starve// concurrent ops of memory. And they might want to set it larger// if I'm completely wrong and larger buffers improve performance.// It's worth trying several MB at least once,although with huge// allocations you have to watch for the linux // "crash on access instead of returning 0" behavIoUr for Failed malloc.#ifndef filecopY_BUFFER_SIZE    #define filecopY_BUFFER_SIZE (64*1024)#endifint copy_data(int fdin,int fdout) {    // optional exercise for reader: take the file size as a parameter,// and don't use a buffer any bigger than that. This prevents     // memory-hogging if filecopY_BUFFER_SIZE is very large and the file    // is small.    for (size_t bufsize = filecopY_BUFFER_SIZE; bufsize >= 256; bufsize /= 2) {        voID *buffer = malloc(bufsize);        if (buffer != NulL) {            int result = copy_data_buffer(fdin,fdout,buffer,bufsize);            free(buffer);            return result;        }    }    // Could use a stack buffer here instead of failing,if desired.    // 128 bytes ought to fit on any stack worth having,but again    // this Could be made configurable.    return -1; // errno is ENOMEM}

打开输入文件:

int fdin = open(infile,O_RDONLY|O_BINARY,0);if (fdin == -1) return -1;

打开输出文件是很巧妙的.作为基础,你想要:

int fdout = open(outfile,O_WRONLY|O_BINARY|O_CREAT|O_Trunc,0x1ff);if (fdout == -1) {    close(fdin);    return -1;}

但有混淆因素:

>你需要特殊情况下文件是一样的,我不记得如何做可移植的.
>如果输出文件名是目录,则可能需要将文件复制到目录中.
>如果输出文件已经存在(使用O_EXCL打开以确定此错误并检查EEXIST是否有错误),则可能需要执行与cp -i不同的 *** 作.
>您可能希望输出文件的权限反映输入文件的权限.
>您可能需要复制其他平台特定的元数据.
>您可能希望或可能不希望取消输出文件的错误.

显然,所有这些问题的答案可能是“做同样的cp”.在这种情况下,原始问题的答案是“忽略我或任何其他人所说的一切,并使用cp的来源”.

获取文件系统的集群大小的Btw是无用的.在您通过磁盘块大小后,您将几乎总是看到速度随着缓冲区大小而增加.

总结

以上是内存溢出为你收集整理的在C中试用和真正的简单文件复制代码?全部内容,希望文章能够帮你解决在C中试用和真正的简单文件复制代码?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1257866.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存