在Visual Studio中fwrite超过4GB

时间:2017-05-09 09:00:48

标签: c++ c visual-studio-2017

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

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

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

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

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

我应该使用其他任何设置吗?

2 个答案:

答案 0 :(得分:2)

使用最旧的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的字节 - 除了简单之外,使用大块调用它没有任何优势内存与使用较小的块进行多次调用并检查返回。

答案 1 :(得分:-1)

我不确定你为什么得到零回报值。每the MS documentation for fwrite()

  

<强>语法

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

为了获得4 GB的输出文件,您已经写了多于零的项目。究竟你怎么知道返回值为零?

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

第三,如果你没有调整FILE *对象的缓冲区大小,它可能会以4或8 KB的块缓冲。关于大多数磁盘系统的性能改进不会导致更大块的大小,这并不是巧合。

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