我用什么来代替管道的GetFileSize()?

时间:2011-09-12 14:37:53

标签: c windows named-pipes

见标题。

在命名管道的客户端,我想确定要从命名管道读取的内容的大小,以便为缓冲区分配内存以获取内容。

MSDN help说:

  

您不能将 GetFileSize 功能与非寻道设备(如管道或通信设备)的句柄一起使用。要确定 hFile 的文件类型,请使用GetFileType函数。

嗯。好的。但是,如果我不能使用GetFileSize来确定管道中可读取的数据量,那么我应该使用什么?目前,我确实

length = GetFileSize(pipehandle, 0);
while(length == 0){
  Sleep(10);                           // wait a bit
  length = GetFileSize(pipehandle, 0); // and try again
}

迟早,length 会得到更大的零,但等待对我来说似乎有点不好。


后台:我有一个管道服务器(大致是来自MSDN example多线程管道服务器)等待客户端连接。连接后,服务器读取文件的内容并使用管道连接将其传递给客户端。


更多背景:我想要这样做的总体原因是我正在使用实现XML解析器的外部库。最初,解析器打开一个文件,然后CreateFileMapping应用于该文件,最后调用MapViewOfFile以获取文件内容。

现在,项目规则已经改变,我们不再允许在磁盘上创建文件,因此我们需要另一种方法将信息从App1(管道服务器)传递到App2(管道客户端)。为了尽可能少地改变,我决定使用管道传递数据,因为在第一个视图中,打开管道与打开任何其他文件相同,我认为我只需做很少的更改就可以去除读数文件,同时能够从管道读取。

目前,我确定管道中数据的大小(我知道它只使用一次将输入文件从App1传递到App2),然后执行malloc来获取缓冲区并读取将管道的全部内容放入缓冲区。

如果我完全离开赛道,我也愿意接受任何更好的建议。

2 个答案:

答案 0 :(得分:2)

显然,在这种情况下你需要一个PIPE_TYPE_BYTE,因为数据量是不可预测的。将其视为客户端中的常规文件,使用较小的缓冲区(例如4096字节)重复调用ReadFile()。如果您需要将它存储在一个数组中,那么您可以先写一个整数,以便客户端知道制作数组的大小。

答案 1 :(得分:1)

如果您使用PIPE_TYPE_MESSAGE类型创建管道,则可以使用PeekNamedPipe方法从管道中检索完整的消息。

PIPE_TYPE_MESSAGE和PIPE_TYPE_BYTE之间的主要区别是:

  • 在MESSAGE类型中,系统管理发送到管道的值的长度,只需要读取一条消息,您将获得所有消息(对于不太大的消息有用,以避免填满所有内存)< / LI>
  • 在BYTE类型中,您必须管理发送数据的长度。也许TLV protocol可能是了解“消息”大小的好方法(也许T-Type部分听起来像是无用的),然后您可以分两部分阅读内容:首先,阅读第一部分字节,它将为您提供消息的大小,然后如果您不想过度填充内存,则按部分读取消息。