如何使用Win32 TransmitFile()传输大于2,147,483,646字节(~2 GiB)的文件?

时间:2013-08-14 19:24:13

标签: sockets winapi visual-c++ transmitfile

引自MSDN entry for TransmitFile

  

使用对TransmitFile函数的单次调用可以传输的最大字节数是2,147,483,646,32位整数的最大值减1.单次调用中发送的最大字节数包括发送的任何数据在lpTransmitBuffers参数指向的文件数据之前或之后加上nNumberOfBytesToWrite参数中指定的值,以发送文件数据的长度。如果应用程序需要传输大于2,147,483,646字节的文件,则可以使用对TransmitFile函数的多次调用,每次调用传输不超过2,147,483,646字节。对于大于2,147,483,646字节的文件,将nNumberOfBytesToWrite参数设置为零也将失败,因为在这种情况下,TransmitFile函数将使用文件的大小作为要传输的字节数的值。

好的。然后,必须将具有TransmitFile的大小为2*2,147,483,646 bytes(~4 GiB)的文件发送至少两部分(例如,在两次调用TransmitFile时为2 GiB + 2 GiB)。但是完全将如何做到这一点,同时最好还保持底层TCP连接在两者之间?

当文件确实大于< = 2,147,483,646字节时,可以写一下:

HANDLE fh = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, 
 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);   

TransmitFile(SOCK_STREAM_socket, fh, 0, 0, NULL, NULL, TF_DISCONNECT);

让Windows处理所有较低级别的东西(缓存,将数据分块为高效传输等等。但是,与可比较的Linux sendfile()系统调用不同,调用中没有立即明显的偏移量参数(虽然第五个论点,LPOVERLAPPED lpOverlapped可能正是我正在寻找的。)我想我可以一起破解某些东西,但我也在寻找一个优雅,良好的练习Win32解决方案。谁真的知道这些东西。

  

您可以使用lpOverlapped参数通过设置OVERLAPPED结构的Offset和OffsetHigh成员来指定文件中开始文件数据传输的64位偏移量。如果lpOverlapped是NULL指针,则数据传输始终从文件中的当前字节偏移量开始。

那么,由于缺乏网上现有的最小例子,哪些电话是完成这项任务所必需的?

1 个答案:

答案 0 :(得分:3)

根据评论进行管理。

因此,如果LPOVERLAPPED lpOverlapped是空指针,则调用将在文件的当前文件偏移量处开始传输(非常类似于Linux sendfile()系统调用及其{{ 1}}参数)。可以使用off_t *offset操纵此偏移量(指针),因此可以编写:

SetFilePointerEx

完成任务。 不是很优雅的imo,但它确实有效。