C++ 如何将一个100 GB的文件拆分为100个1 GB的文件?
当我试图解决这个问题时,我想到了这个问题 我有容量为120GB的硬盘,其中100GB被一个巨大的文件占用。所以20GB仍然是免费的 我的问题是,我们如何将这个巨大的文件分割成更小的文件,比如说每个1 GB?我发现,如果我有大约100GB的可用空间,那么使用简单的算法可能是可行的。但如果只有20GB的可用空间,我们最多可以写入201GB的文件。我不知道如何在读取大文件时删除其中的内容 有解决办法吗 一旦我完成一个文件的编写,我似乎必须将该文件截断1GB,但这归结为以下问题: 是否可以截断文件的一部分?到底是怎么回事C++ 如何将一个100 GB的文件拆分为100个1 GB的文件?,c++,c,algorithm,file,hard-drive,C++,C,Algorithm,File,Hard Drive,当我试图解决这个问题时,我想到了这个问题 我有容量为120GB的硬盘,其中100GB被一个巨大的文件占用。所以20GB仍然是免费的 我的问题是,我们如何将这个巨大的文件分割成更小的文件,比如说每个1 GB?我发现,如果我有大约100GB的可用空间,那么使用简单的算法可能是可行的。但如果只有20GB的可用空间,我们最多可以写入201GB的文件。我不知道如何在读取大文件时删除其中的内容 有解决办法吗 一旦我完成一个文件的编写,我似乎必须将该文件截断1GB,但这归结为以下问题: 是否可以截断文件的一部
<>我想看到一个算法(或者一个算法的大纲),它在C或C++中(最好是标准C和C++),<强>,这样我就可以知道较低的细节< <强> >。我不是在寻找一个可以完成这项工作的神奇函数、脚本或命令。这项工作没有标准函数 对于Linux,您可以使用该方法,而对于Windows,您可以使用或。一个简单的
#ifdef
将使其跨平台。
另请阅读Q&A.,根据您应该能够在兼容POSIX的系统上使用调用来调整现有文件的大小
现代实现可能会“就地”调整文件的大小(尽管文档中未指定)。唯一的问题是,您可能需要做一些额外的工作来确保off\t
是64位类型(POSIX标准中有关于32位off\t
类型的规定)
您应该采取措施处理错误情况,以防由于某种原因失败,因为很明显,任何严重的失败都可能导致100GB文件丢失
伪代码(假设并采取措施确保所有数据类型都足够大以避免溢出):
显然,其中一些伪代码类似于标准库中的函数。在其他情况下,您必须自己编写。您必须从源文件的末尾开始工作。拆分1gig块,将源文件截断1gig,等等。。。你不能从前面这样做,因为这需要你复制整个文件,你的空间就不够了。@nawaz:对不起,但我认为有110k rep的人可以自己用谷歌搜索ftruncate()信息……如果只使用标准函数,你必须小心。通常情况下,我不得不求助于非标准扩展名来正确处理大于4GB的文件。@brianbeuning:可以增大较大文件的大小,并提出相同的问题。所以你的50美元帮不上忙。@Nawaz:如果它正在截断它,那么你打开它的标志是错误的。我编辑了我的问题。现在它说:“我想看到一个算法(或者一个算法的大纲),它在标准的C或C++中工作,所以我可以知道较低的细节。我不想仅仅一些解决方案,脚本或命令可以完成这个任务。”@纳瓦兹:没有标准的C++工具允许你跨平台可靠地完成这一任务。您需要依赖操作系统特定的函数,如
\u chsize
和ftruncate
,或者依赖第三方库,如boost::filesystem
,它们包装这些函数调用。至少在文件系统
被采纳到标准中之前,这应该很快就会被采纳。@Nawaz:你说的较低级别的细节是什么意思?您想让我解释一下,如何打开硬驱动程序的句柄,并使用FAT32库自己跟踪文件集群链,以便自己截断该链?如果是这样的话,那么你就离跨平台和标准更远了。@WouterHuysentruit:我的意思是,如果我自己实现ftruncate
功能,我会怎么做?算法是什么?只需遵循文件集群链,修改应该发生截断的集群的长度,并更新分配表。非常简单,但依赖于文件系统。除了您的答案,如果还不明显,我建议开发人员在实际交易之前在另一个系统上进行测试,以确保他们的代码中没有愚蠢的错误。。。当你只有一次机会时,你要确保你不会错过
open (string filename) // opens a file, returns a file descriptor
file_size (descriptor file) // returns the absolute size of the specified file
seek (descriptor file, position p) // moves the caret to specified absolute point
copy_to_new_file (descriptor file, string newname)
// creates file specified by newname, copies data from specified file descriptor
// into newfile until EOF is reached
set descriptor = open ("MyHugeFile")
set gigabyte = 2^30 // 1024 * 1024 * 1024 bytes
set filesize = file_size(descriptor)
set blocks = (filesize + gigabyte - 1) / gigabyte
loop (i = blocks; i > 0; --i)
set truncpos = gigabyte * (i - 1)
seek (descriptor, truncpos)
copy_to_new_file (descriptor, "MyHugeFile" + i))
ftruncate (descriptor, truncpos)