2015-04-27 54 views
-1

我想使用curl从多个部分同时使用多线程下载数据从互联网。但是,当下载完成时,我遇到了问题,我必须将所有部分合并在一起,这会浪费内存并耗费很长时间。如何分配磁盘中的文件来写入数据C++

我看到Torrent和Flashget使用这种技术,我的名字我不知道。在下载之前,Torrent获取文件的内容长度并自动在磁盘中分配一个空文件。之后,如果下载恢复,则下载的数据将填充此分配的文件。 Torrent或Flashget会检查这个分配的文件以获取它已经下载的字节,然后他们恢复下载。

任何人都可以用这种技术来帮助我,或者给我一些关于这个文件的链接?如果你可以用c#或C++建议我的例子,那将会很棒。写作

1.打开文件:感谢您的帮助

+1

那么你可以[SetFilePointer](https://msdn.microsoft.com/en-us/library/windows/desktop/aa365541(v = vs.85).aspx)任意长度,然后[SetEndOfFile ](https://msdn.microsoft.com/en-us/library/windows/desktop/aa365531(v = vs.85).aspx)来扩展它,但我不确定这将有助于_“Torrent或Flash获取将检查此分配文件以获取字节已下载并恢复下载“_”。你需要跟踪下载的内容。 _ [这可能也有用](http:// stackoverflow。com/questions/12434306/in-general-how-do-resuming-a-download-work)_ – MickyD

+0

你是指稀疏文件吗? https://msdn.microsoft.com/en-us/library/windows/desktop/aa365564%28v=vs.85%29.aspx –

回答

0

预分配磁盘上的文件,你可以做以下。

HANDLE file = CreateFile("some_file.bin", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 

2.移动文件指针到所需的位置。

LONG download_size = /* check, how much data is going to be downloaded */; 
SetFilePointer(file, download_size, NULL, FILE_BEGIN); 

物理扩展文件。

SetEndOfFile(file); 

的更多信息:


至于这一部分:

检查此分配文件以获取字节已下载并恢复下载。

你可以通过存储具有标题的自定义格式的部分下载来实现这一点。例如,定义一个结构:

struct TmpDownloadInfo 
{ 
    uint32_t header_size; 
    size_t downloaded_bytes; 
    //other fields? 
}; 

然后,在文件存储临时数据,即始于此标题,并更新其在每次修改(当然,要记住,在这种情况下,你将需要预先分配download_size + sizeof(TmpDownloadInfo) )。下载完成后,您可以删除此标题并更新文件大小,也可以将整个数据复制到新的结果文件(也许“即时”合并)。

+0

谢谢@Mateusz Grzejek。即时通讯使用你的建议和预先分配文件成功。但即时通讯使用WriteFile将数据写入预分配文件,但不成功。这里我的问题[链接](http://stackoverflow.com/questions/30188022/libcurl-write-data-with-writefile-winapi) –