由于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中试用和真正的简单文件复制代码?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)