在Debian Linux中快速创建一个非常大的文件

时间:2013-05-27 10:58:29

标签: c linux debian

我目前正在开发一个涉及将一个非常大的文件(大约6GB)从一个Linux服务器传输到另一个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分钟。有没有办法更快地创建空文件?我做错了什么?

感谢您的时间。

此致 尼克

5 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分:5)

首先creat该文件,然后lseek到所需的结尾,write一个虚拟字节。创建任意大型sparse文件的快速方法。


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

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

答案 2 :(得分:3)

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

fallocate -l 6GB hugefile

It预先将块分配给文件。

答案 3 :(得分:1)

创建大型文件需要很长时间,因为操作系统必须在文件系统上进行很多操作。只有在稀疏文件的情况下才可以跳过这个(参见Joachim Pileborg的答案)。稀疏文件是包含“漏洞”(大块零字节)的文件。这样的文件不会占用太大的空间。事先创建这样的文件将非常快速地生成具有正确大小的文件。

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

答案 4 :(得分:0)

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

在性能方面,这种方法非常好。