在Windows上创建大文件

时间:2009-01-18 15:18:19

标签: c windows file file-io

我需要创建大的相对较大(1-8 GB)的文件。使用C或C ++在Windows上执行此操作的最快方法是什么?我需要动态创建它们,速度确实是一个问题。文件将用于存储仿真,即将在不同的偏移量中随机访问,我需要预先分配所有存储但未初始化,目前我们正在使用虚拟数据写入所有存储,并且花费的时间太长。

感谢。

6 个答案:

答案 0 :(得分:26)

使用Win32 API,CreateFileSetFilePointerExSetEndOfFileCloseHandle。以同样的顺序。

技巧在SetFilePointerEx函数中。来自MSDN:

  

请注意,设置不是错误   指向超出位置的文件指针   文件的结尾。的大小   在你打电话之前,文件不会增加   SetEndOfFile,WriteFile或   WriteFileEx函数。

当将文件从一个位置复制到另一个位置时,Windows资源管理器实际上也会这样做。它这样做是为了使磁盘不需要为碎片磁盘重新分配文件。

答案 1 :(得分:2)

查看memory mapped files

它们非常符合您描述的用例,高性能和随机访问。

我认为不需要将它们创建为大文件。您只需在它们上设置一个较大的最大尺寸,当您写入之前未触及的零件时,它们将被展开。

答案 2 :(得分:1)

使用“fsutil”命令:

E:\ VirtualMachines> fsutil文件createnew 用法:fsutil文件createnew    例如:fsutil文件createnew C:\ testfile.txt 1000

Reagds

P.S。适用于Windows:2000 / XP / 7

答案 3 :(得分:1)

this解决方案也不错,但你要找的是SetFileValidData

作为MSDN sais:

  

SetFileValidData函数允许您避免使用填充数据   在非顺序写入文件时为零。

因此,这始终保留磁盘数据,SetFilePointerEx应将所有数据设置为零,因此大量分配需要一些时间。

答案 4 :(得分:0)

如果你正在使用NTFS,那么sparse files就可以了:

  

大部分数据所在的文件   据说零包含稀疏数据   组。像这样的文件通常是   非常大 - 例如,一个文件   包含要处理的图像数据   或高速内的矩阵   数据库。文件的问题   包含稀疏数据集的是   大多数文件没有   包含有用的数据,因为   对此,它们的使用效率低下   磁盘空间。

     

NTFS文件中的文件压缩   系统是部分解决方案   问题。文件中的所有数据都是   未明确写明是明确的   设为零。文件压缩紧凑   这些范围的零。但是,一个   文件压缩的​​缺点是   访问时间可能会因数据而增加   压缩和减压。

     

引入了对稀疏文件的支持   在NTFS文件系统中作为另一种方式   使磁盘空间使用更多   高效。当稀疏文件   功能已启用,系统   不分配硬盘空间   除了在其中的区域之外的文件   包含非零数据。写的时候   在大的地方尝试操作   缓冲区中的数据量是   零,零不写入   文件。相反,文件系统   创建一个包含的内部列表   中的零点的位置   文件,并查阅此列表   在所有阅读操作中。当一个   读取操作在区域中执行   零所在的文件,   文件系统返回   适当数量的零   为读取分配的缓冲区   操作。这样,维护   稀疏文件对所有人都是透明的   访问它的进程,更多   比压缩效率更高   特殊情况。

答案 5 :(得分:0)

我知道您的问题是用Windows标记的,如果您确定知道您不必将应用程序移植到其他平台,Brian R. Bondy会为您提供最佳答案。但是,如果您可能需要将应用程序移植到其他平台,您可能想要做更像Adrian Cornish提出的问题,作为“如何创建”x“大小的文件?”的答案。发现于How to create file of "x" size?

FILE *fp=fopen("myfile", "w");
fseek(fp, 1024*1024, SEEK_SET);
fputc('\n', fp);
fclose(fp);

当然,还有一个额外的转折点。 Adrian Cornish提出的答案利用了具有以下特征的fseek函数。

int fseek ( FILE * stream, long int offset, int origin );

问题是您要创建一个文件大小超出32位整数范围的非常大的文件。您需要使用64位等效的fseek。不幸的是,在不同的平台上它有不同的名称。

http://mosaik-aligner.googlecode.com/svn-history/r2/trunk/src/CommonSource/Utilities/LargeFileSupport.h找到的头文件LargeFileSupport.h提供了解决此问题的方法。

这将允许您编写以下函数。

#include "LargeFileSupport.h"
/* Include other headers. */

bool createLargeFile(const char * filename, off_type size)
{
    FILE *fp = fopen(filename, "w");
    if (!fp)
    {
        return false;
    }
    fseek64(fp, size, SEEK_SET);
    fputc('\n', fp);
    fclose(fp);
}

我想我会添加这个,以防这些信息对您有用。