开发者

What do I use as replacement of GetFileSize() for pipes?

See title.

On the client side of an named pipe, I want to determine the size of the content to be read from a named pipe in order to allocate memory for a buffer to take the content.

The MSDN help says:

You cannot use the GetFileSize function with a handle of a nonseeking device such as a pipe or a communications device. To determine the file type for hFile, use the GetFileType function.

Hmmm. Okay. But if I cannot use GetFileSize to determine the amount of data being readable from a pipe, what shall I use then? Currently, I do

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

Sooner or later, length does get greater zero, but the waiting seems a bit bad to me.


Background: I have a pipe server (roughly the Multithreaded Pipe Server from the MSDN example) that waits for the client to connect. Upon connection, the server reads the content of a file and passes that to the client using the pipe connection.


More Background: The overall reason why I want to do that is that I'm working with an external library that implements an XML parser. Originally, the parser opens a file, then CreateFileMapping is applied to that file and finally MapViewOfFile is being called in order to get the file content.

Now, the project rules have changed and we're no longer allowed to create files on the disk, so we need another way to pass the information from App1 (the pipe server) to App2 (the pipe client). To change as less as possible, I decided to use pipes for passing the data because on the first view, opening a pipe is the same as opening any other file and I assume that I have to do only very few changes to get rid of reading files while being able to read from pipes.

Currently, I determine the size of the data in the pipe (I know that it is used only once to pass the input file from App1 to App2), then do a malloc to g开发者_StackOverflowet a buffer and read the whole content of the pipe into that buffer.

If I'm on a completely off the track, I'd also be open for any suggestions to do things better.


Clearly you want a PIPE_TYPE_BYTE in this case since the amount of data is unpredictable. Treat it just like a regular file in the client, calling ReadFile() repeated with a small buffer of, say, 4096 bytes. If your need is to store it in an array then you could simply write an integer first so that the client knows how big to make the array.


If you created your pipe in a PIPE_TYPE_MESSAGE type, you will be able to use the PeekNamedPipe method to retrieve a complete message from the pipe.

The main difference between PIPE_TYPE_MESSAGE and PIPE_TYPE_BYTE are :

  • in MESSAGE type, the system is managing the length of the value sent into the pipe, just ask to read one message and you will get all the message (usefull for not too large message to avoid to fill all the memory)
  • in BYTE type, you have to manage the length of the data you send threw the pipe. Maybe a TLV protocol could be a good way to know the size of your "messages" (maybe the T-Type part sounds like a useless one), you can then read the content in two parts : first, read the first bytes which will give you the size of the message, and then read message by parts if you don't want to overfill the memory.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜