gpt4 book ai didi

algorithm - 将一个文件复制到另一个文件并返回复制的字节数

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:34:32 26 4
gpt4 key购买 nike

一开始这看起来很简单,但这是一个面试问题,技巧如下:

我编写了一个简单的代码来将 Bytewise 从一个文件复制到另一个文件并返回在 while(!feof) 循环中递增的计数。然而,我的面试官说执行这个复制 1 GB 文件的循环将花费 1 小时,因为它是按字节复制的,但这在现实生活中并没有发生。谁能告诉我大文件实际上是如何在计算机上复制的,底层算法是什么?另外,请记住我需要返回复制的字节数。

最佳答案

他可能完全错了。

除非您使用汇编语言之类的语言编写代码,否则一次读/写一个字符几乎肯定只会对整体速度产生相当小的影响。原因很简单:几乎任何比汇编语言更高级别的语言都会在您进行面向字符的 I/O 时为您提供(至少一些)缓冲。

举个例子,考虑这样的 C 代码:

#include <stdio.h>

int main(int argc, char **argv) {
FILE *infile = fopen(argv[1], "rb");
FILE *outfile = fopen(argv[2], "wb");

unsigned long count = 0;
int ch;

while (EOF != (ch=getc(infile))) {
++count;
putc(ch, outfile);
}
printf("%lu bytes copied\n", count);
return 0;
}

实际情况是,这可能会比典型的文件复制慢一点,但只是一点。原因很简单:至少假设 C、getcputc(连同大多数标准 I/O 的其余部分)的中等实现将进行缓冲为你在幕后。事实上,getc 和 putc 通常会作为宏来实现,因此大部分代码也会被内联扩展。虽然它因编译器而异,但典型的代码看起来像这样:

#define getc(f) f->__pos<f->__len?f->__buf[f->__pos++]:__filbuf()
#define putc(ch, f) f-__>pos<f->__len?f->__buf[f->__pos++]=ch:__flshbuf(f, ch)

这将伴随着类似这样的代码:

#define BUF_SIZE 4096

typedef struct {
char __buf[BUF_SIZE];
size_t __pos;
size_t __len=BUF_SIZE;
int __file_number;
} FILE;

现在,您确实可以改进这一点:

  1. 因为您知道您将按顺序使用整个文件,所以您可以使用更大的缓冲区来减少往返内核模式的次数。
  2. 因为您知道您将完全按照写入的方式写入数据,所以您可以读入缓冲区,然后使用完全相同的缓冲区进行写入,而不是将数据从一个缓冲区复制到另一个缓冲区。
  3. 既然您知道您正在复制文件,而且大部分数据很可能不会很快再次使用,您可能会告诉您的操作系统不应缓存这些数据。
  4. 如果源和目标位于物理上不同的磁盘上,异步 I/O 可能会有所帮助,因为它允许同时进行读/写。

但是请注意,这些可能会增加相当多的开发时间,即使充其量您也不应该计划看到面试官建议的速度差异。即使是 10 倍的改进也不太可能,更不用说面试官建议的 ~1000 倍了。

关于algorithm - 将一个文件复制到另一个文件并返回复制的字节数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7691338/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com