繁体   English   中英

在Visual Studio中写入超过4GB

[英]fwrite more than 4GB in Visual Studio

我试图设置我的视觉工作室,以便可以一次fwrite 8GB。

我可以看到malloc通过使用监视器跟踪内存来分配8GB。

但是,fwrite的返回值为零,并且输出文件大小仅为4GB。

size_t s = fwrite(result, sizeof(unsigned int), 0x80000000, fout);

我正在使用x64,发布模式。

我应该使用其他设置吗?

使用最早的C运行时函数来处理大数据并没有多大意义,因为Windows API和C ++都有更好的方法来处理大数据,例如内存映射文件。 对于C ++内存映射文件,boost有两种实现。

如果您真的想使用fwrite,请尝试将其拆分,因为Visual C ++的fwrite实现不会一口气写出大数组:

fwrite是在Windows WriteFile函数的顶部实现的,该函数只能写入一个DWORD字节的字节,此外,还可以从其实现中看到此注释,该注释位于C:\\ Program Files(x86)\\ Microsoft Visual Studio 12.0 \\ VC \\ crt \\ src中\\ fwrite.c。

/***
*size_t fwrite(void *buffer, size_t size, size_t count, FILE *stream) -
*       write to the specified stream from the specified buffer.
*
*Purpose:
*       Write 'count' items of size 'size' to the specified stream from
*       the specified buffer. Return when 'count' items have been written
*       or no more items can be written to the stream.
*
*Entry:
*       buffer  - pointer to user's buffer
*       size    - size of the item to write
*       count   - number of items to write
*       stream  - stream to write to
*
*Exit:
*       Returns the number of (whole) items that were written to the stream.
*       This may be less than 'count' if an error or eof occurred. In this
*       case, ferror() or feof() should be used to distinguish between the
*       two conditions.
*
*Notes:
*       fwrite will attempt to buffer the stream (side effect of the _flsbuf
*       call) if necessary.
*
*       No more than 0xFFFE bytes may be written out at a time by a call to
*       write(). Further, write() does not handle huge buffers. Therefore,
*       in large data models, the write request is broken down into chunks
*       that do not violate these considerations. Each of these chunks is
*       processed much like an fwrite() call in a small data model (by a
*       call to _nfwrite()).
*...

请注意, 通过调用write()一次可以写出开头不超过0xFFFE字节的部分-除了简单性之外,与使用多个较小的块进行多次调用相比,使用较大的内存块进行调用没有优势。检查退货。

我不确定为什么您会得到零返回值。 根据fwrite()的MS文档

句法

 size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream ); 

您已编写了超过零个项目,以获得4 GB的输出文件。 您究竟怎么知道返回值为零?

其次,试图在一行代码中写如此大的数量没有意义-总是可以进行部分写操作,其中任何大小的写尝试都可能导致少于该数量的写操作。 而且,当您一次写入千兆字节时,极有可能发生部分写入,因此无论如何您都必须编写代码来处理部分写入。 从性能角度看,即使在极高速的磁盘系统上,一旦写入大小达到兆字节范围,您将不再看到性能的提高。 在消费级商品系统上,一旦您的写入请求达到几千字节,性能可能就不会提高。

第三,如果您不调整FILE *对象的缓冲区大小,则它可能仍以4或8 KB的块进行缓冲。 这并不是一个巧合,它的大小不会使大多数磁盘系统的性能有很大的提高。

最后,正如@Andriy Berestovskyy在回答中所说,您可能会遇到文件系统限制。 查看是否可以使用多个fwrite()调用写入大于4GB的文件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM