1

我目前正在从事一个项目,该项目涉及将一个非常大的文件(大约 6GB)从一个 Linux 服务器传输到另一个。这些服务器在 Debian Squeeze 上运行。为了实现我的主要目标,我最初将文件的名称和大小发送到目标机器,然后创建一个空文件来存储从源机器逐步接收的数据块。我的问题是在我的服务器上创建一个 6GB 的文件需要很长时间。为了更清楚,我使用以下 C 例程来创建新文件:

void create_file(char* f_name, long long f_size) {
    char* bs, *of, *s_f_size, *count;
    if((pid = fork()) < 0) {
            perror("fork() failed.");
            return;
    }
    if(pid == 0) {
        //Call execl
        of = (char*) malloc(sizeof(char)*(strlen("of=") + strlen(f_name) + 1));
        s_f_size = (char*) malloc(sizeof(char)*32);
        sprintf(s_f_size, "%lld", file_size);
        count = (char*) malloc(sizeof(char)*(strlen("count=") + strlen(s_f_size) + 1));
        strcpy(of, "of=");
        strcat(of, f_name);
        strcpy(count, "count=");
        strcat(count, s_f_size);
        ret = execl("/bin/dd", "dd", "if=/dev/zero", of, "bs=1", count, (char*) 0);
        if(ret < 0) {
            perror("execl() failed");
            free(s_f_size);
            free(of);
            free(count);
            return;
        }else {
            free(s_f_size);
            free(of);
            free(count);
            return;
        }
    }else {
        status = 0;
        wpid = wait(&status);

    }
}

我使用 Linux dd 命令是因为我认为这将是创建一个空的 6GB 文件的最快方法。但是,大约需要 15 分钟才能完成。有没有办法更快地创建空文件?我究竟做错了什么?

感谢您的时间。

真诚的,尼克

4

5 回答 5

7

除了 Joachim Pileborg 的建议外,您还可以使用posix_fallocate()它为文件预先分配空间。

于 2013-05-27T11:07:52.530 回答
5

首先creat是文件,然后lseek是想要的结尾,然后write是一个虚拟字节。创建任意大但稀疏文件的非常快速的方法。


如果您不希望文件稀疏,请找出驱动器的块大小(可以stat在大多数 POSIX 平台上使用)。创建该大小的缓冲区,并将其写入文件直到所需大小。

如果stat结构没有st_blksize成员,那么大多数文件系统的块大小为 4 或 8 kB。您可能可以使此缓冲区更大,但不能太大。实验和基准测试!

于 2013-05-27T11:01:10.207 回答
4

如果您使用的是内核 v2.6.31+ 并且文件系统支持它,请考虑使用fallocate

fallocate -l 6GB hugefile

它将块预分配给文件。

于 2013-05-27T11:13:07.843 回答
1

创建大文件需要很长时间,因为操作系统必须在文件系统上做很多事情。只有在文件稀疏的情况下才能跳过(请参阅 Joachim Pileborg 的答案)。稀疏文件是包含“漏洞”(零字节的大块)的文件。这样的文件使用的空间不像它那么大。事先创建这样的文件将很快生成正确大小的文件。

如果您想保留磁盘空间以避免在传输完成之前用完它,稀疏文件将不会做。您必须在每个块中至少写入一个字节,以避免稀疏文件的漏洞。我不确定这会比简单地将零转储到文件中要快,直到它具有所需的大小,就像你已经做的那样。

于 2013-05-27T11:10:14.987 回答
0

我记得,我使用开放系统调用来创建一个空文件。然后将数据转储到文件中。在部分数据写入的情况下,继续寻找位置并从那里转储。如果文件存在,则使用该文件将数据覆盖到其中。

就性能而言,这种方法非常好。

于 2013-05-27T11:05:14.270 回答