2009-01-18 83 views
15

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

谢谢。

回答

26

使用Win32 API,CreateFile,SetFilePointerEx,SetEndOfFileCloseHandle。以同样的顺序。

诀窍在SetFilePointerEx函数中。从MSDN:

请注意,这是不是一个错误设置 文件指针的位置超越 文件的末尾。在调用 SetEndOfFile,WriteFile或WriteFileEx函数之前, 文件的大小不会增加。

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

+0

经过测试,它如期工作,感谢Brian。 – Ilya 2009-01-18 16:26:20

+0

这将只在NTFS和exFAT上运行,而不是在FAT32,FAT16上。 这是因为这些文件系统有一个“初始化大小” – 2010-08-25 18:30:35

+0

“SetEndOfFile()”在写入文件时会导致严重的延迟。如果您将文件写入文件的中间,则Windows将会将所有尚未写入的块清零,直至写入的位置。参见http://blogs.msdn.com/b/oldnewthing/archive/2011/09/22/10215053.aspx(我可以亲自证实这一点,在编写IO基准测试应用程序时我亲眼目睹了这种效果。) – 2014-02-14 14:23:30

2

结账memory mapped files

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

我相信他们不需要被创建为大文件。你只需在它们上面设置一个很大的最大尺寸,当你写下你以前没有碰过的零件时它们就会被扩大。

0

如果您使用NTFS然后sparse files是要走的路:

其中许多数据是 零的文件据说含有稀疏数据 集。像这些文件通常是非常大的 - 例如,文件 包含要处理的图像数据 或高速数据库内的矩阵。包含稀疏数据集的文件 的问题是 大部分文件不包含 包含有用的数据,并且由于 这样,它们的磁盘空间使用效率低下 。

NTFS文件 系统中的文件压缩是 问题的部分解决方案。文件中未明确写入的所有数据 明确为 设为零。文件压缩契约 这些范围为零。但是,文件压缩的​​缺点在于 访问时间可能由于数据 压缩和解压缩而增加。

支持稀疏文件介绍 在NTFS文件系统中的另一种方式 使磁盘空间的使用更加高效 。当启用稀疏文件 功能时,系统 不会为文件分配硬盘空间至 文件,但 包含非零数据的区域除外。当尝试写入 操作,其中缓冲区中的大量数据量为 零时,零不会写入 文件。相反,文件系统 创建了一个包含 文件中零的位置的内部列表,并且在所有读取操作期间向该列表查询 。当所在的地区零均位于该文件的 执行 读操作, 文件系统返回分配给读 操作 缓冲零的 适当数量。通过这种方式,稀疏文件的维护对于访问它的所有 进程都是透明的,并且对于此特定场景的压缩效率更高,为 。

0

使用 “FSUTIL” 命令:

E:\ VirtualMachines> FSUTIL文件createnew 用法:FSUTIL文件createnew 例如:FSUTIL文件createnew C:\ TESTFILE.TXT 1000

Reagds

PS它是Windows 2000/XP/7

1

this的解决方案是不坏,但你正在寻找的东西是SetFileValidData

由于MSDN赛斯:

的SetFileValidData功能允许您避免在向文件不连续写入时用 填充数据。

因此,这总是将磁盘数据保留原样,SetFilePointerEx应将所有数据设置为零,因此大的分配需要一些时间。

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位整数范围的非常大的文件。您需要使用fseek的64位等价物。不幸的是,在不同的平台上它有不同的名字。

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); 
} 

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