我搜索过TON,找到一种方法,使用fstream或其他方法,将数据写入大文件,但没有找到任何答案。
我的问题是,我从互联网上下载数据,然后将数据写入预先分配的文件。对于小于2GB的文件,一切似乎都没问题,但是当使用大于2GB的预分配文件进行尝试时,将流指针移动到预分配文件中的特定位置(例如文件的最后位置)时会出错写数据,似乎无法做到,tellp allway返回-1。
这是我的写入数据方法,因为写入预分配文件,我不使用FILE或boost:iosstream。我使用Visual Studio 2008和.Net 3.5。感谢阅读并帮助我^。^
size_t writeData(void *ptr, size_t size, size_t nmemb, Downloader *objDownloader){
size_t written;
if (objDownloader->_stop == false && objDownloader->mystream.is_open()){
objDownloader->mystream.seekp(objDownloader->_posSeek, ios::beg);
written=size * nmemb;
objDownloader->mystream.write(static_cast<char*>(ptr), written);
objDownloader->_posSeek += size*nmemb;
objDownloader->_downloaded += size*nmemb;
objDownloader->mystream.seekp(objDownloader->_currentPosition, ios::beg);
objDownloader->mystream.write((char*)&objDownloader->_downloaded, sizeof(long long));
long long pos = objDownloader->mystream.tellp();
cout << "POS TEL: " << pos << endl;
return size * nmemb;
}
else{
if (objDownloader->mystream.is_open())
objDownloader->mystream.close();
return -1;
}
}
答案 0 :(得分:3)
您的问题与fstream无关,但与处理内存无关。
以下代码将生成3GB的文件,没有任何问题,使用tellp()
显示进度,并使用seekp()在文件末尾的位置:
cout << "size_t is limted to " << numeric_limits<size_t>::max() << " bytes (" << numeric_limits<size_t>::max() /1024/1024<<" MB)"<< endl;
cout << "streamsize is limited to " << numeric_limits<streamsize>::max() << " bytes (" << numeric_limits<streamsize>::max() / 1024 / 1024/1024/104 << " TB)" << endl;
static char mbloc[1024*1024];
fill_n(mbloc, sizeof(mbloc), 'A');
const size_t blocs = 3*1024;
ofstream os("test.out");
for(int i = 0; i < blocs && os; i++) {
os.write(mbloc, sizeof(mbloc));
if(i % 512)
cout << "tellp() -> " << os.tellp() << "\r";
}
cout << endl;
os.seekp(0, ios::end);
cout << os.tellp() << " end"<<endl;
os.close();
cout << "File generation finished";
事实上,fstreams被认为是非常大的。这就是ostream::write()
使用streamsize
类型计数的原因。
事实上,tellp()返回-1,因此发生了另一次失败。您可以通过检查fstream操作的状态来识别此故障的根源,以确定哪些成功以及哪些成功失败。
您的声明显示您尝试从内存缓冲区写入所有内容:
objDownloader->mystream.write(static_cast<char*>(ptr), written);
很遗憾,在Windows下,您将遇到2GB that applies to a 32 bit process限制的问题。这可能会导致写入失败,不是因为fstream限制,而是因为底层操作系统的内存限制。
如果编译为64位并在64位进程上运行,如果计算机上有足够的内存,则可以将此限制扩展到8TB。但是如果你操纵这么大的数据,你最好用较小的块写在磁盘上,而不必将整个文件保存在内存中。