2011-09-12 33 views
2

查看标题。如何替换管道的GetFileSize()?

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

MSDN help说:

您不能使用GetFileSize功能与nonseeking装置的手柄,如管道或通信设备。要确定文件类型h文件,请使用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

为什么你需要文件大小?有没有一种方法可以执行与流操作相同的任务,而不是分配空间将整个文件存储在内存中?没有真正的方法来获取管道的“文件大小”,因为它没有任何有意义的定义。一个管道继续提供数据,直到没有更多的数据可供使用,并且在此之前无法分辨出有多少数据。它甚至可以是无限的。 – BishopRook

+0

@BishopRook:扩展问题提供更多背景。 – eckes

回答

2

很明显,在这种情况下你想要一个PIPE_TYPE_BYTE,因为数据量是不可预测的。对待它就像客户端中的常规文件一样,使用4096字节的小缓冲区重复调用ReadFile()。如果你需要将它存储在一个数组中,那么你可以简单地写一个整数,这样客户端就知道该数组有多大。

+0

+1用于*先写整数*。我会试一试。 – eckes

1

如果您在PIPE_TYPE_MESSAGE类型创建你管,你将能够使用PeekNamedPipe方法来检索从管道的完整信息。

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

    在留言类型
  • ,系统管理送入管的值的长度,就问我读一个消息,你会得到所有的消息(为了避免填充所有内存,请使用不要太大的消息)
  • BYTE类型,您必须管理您发送的数据的长度。也许一个TLV protocol可能是一个很好的方法来知道你的“消息”的大小(也许T型部分听起来像一个无用的),然后你可以阅读的内容分为两部分:首先,读取的第一个字节将给你是消息的大小,如果你不想过度填充内存,然后按部分读消息。
+0

目前,它是'PIPE_TYPE_BINARY',因为我无法弄清楚'PIPE_TYPE_MESSAGE'和'BINARY'对我来说听起来更容易。主要区别是什么? – eckes

+0

@eckes:编辑我的答案,试图解释我看到的主要差异。 –

+0

+1,用于清楚地指出* message *和* bype *类型之间的区别。 – eckes