c - Hvad bruger jeg som erstatning for GetFileSize () til rør?

Indlæg af Hanne Mølgaard Plasc

Problem



Se titlen.


På klientsiden af ​​et navngivet rør vil jeg bestemme størrelsen på det indhold, der skal læses fra et navngivet rør, for at tildele hukommelse til en buffer for at tage indholdet.


MSDN-hjælpen siger: [6]



  Du kan ikke bruge funktionen GetFileSize med et håndtag af en nonseeking-enhed, såsom et rør eller en kommunikationsenhed. For at bestemme filtypen for hFile skal du bruge funktionen GetFileType. [7]



Hmmm. Okay. Men hvis jeg ikke kan bruge GetFileSize til at bestemme mængden af ​​data, der kan læses fra et rør, hvad skal jeg da bruge? I øjeblikket gør jeg [8]


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


Før eller senere length får større nul, men ventetiden virker lidt dårligt for mig.





Baggrund: Jeg har en pipeserver (omtrent Multithreaded Pipeserver fra MSDN-eksempelet), der venter på, at klienten tilslutter. Ved tilslutning læser serveren indholdet af en fil og overfører det til klienten ved hjælp af rørforbindelsen. [9]





Mere baggrund: Den overordnede årsag til, at jeg vil gøre det er, at jeg arbejder med et eksternt bibliotek, der implementerer en XML-parser. Oprindeligt åbner parseren en fil, så er CreateFileMapping anvendt til den fil og endelig MapViewOfFile bliver kaldt for at få filindholdet. [10] [11]


Nu er projektets regler ændret, og vi har ikke længere lov til at oprette filer på disken, så vi har brug for en anden måde at videregive oplysningerne fra App1 (pipeserveren) til App2 (rørklienten). At ændre så lidt som muligt besluttede jeg at bruge rør til at overføre dataene, fordi i første visning er åbning af et rør det samme som åbning af en anden fil, og jeg antager, at jeg kun skal gøre meget få ændringer for at slippe af med at læse filer, mens jeg er i stand til læs fra rør.


I øjeblikket bestemmer jeg størrelsen på dataene i røret (jeg ved, at den kun bruges én gang til at sende indlæsningsfilen fra App1 til App2), og gør derefter en malloc for at få en buffer og læse hele indholdet af røret ind i den buffer.


Hvis jeg er helt væk fra banen, er jeg også åben for forslag til at gøre tingene bedre.

Bedste reference


Det er klart, at du vil have en PIPE\_TYPE\_BYTE i dette tilfælde, da mængden af ​​data er uforudsigelig. Behandle det ligesom en almindelig fil i klienten, kaldet ReadFile () gentaget med en lille buffer på, siger 4096 bytes. Hvis dit behov er at gemme det i en matrix, så kan du simpelthen skrive et helt tal først, så klienten ved, hvor stor det er at lave arrayet.

Andre referencer 1


Hvis du har oprettet dit rør i en PIPE\_TYPE\_MESSAGE type, kan du bruge PeekNamedPipe-metoden til at hente en komplet besked fra røret. [12]


Hovedforskellen mellem PIPE\_TYPE\_MESSAGE og PIPE\_TYPE\_BYTE er:



  • i MESSAGE type, styrer systemet længden af ​​værdien, der sendes ind i røret. Bare spørg om at læse en besked, og du får al meddelelsen (nyttig for ikke for stor besked for at undgå at fylde hele hukommelsen)

  • i BYTE-typen, skal du styre længden af ​​de data, du sender kastet røret. Måske kan en [13] TLV-protokol være en god måde at kende størrelsen på dine 'beskeder' på (måske T-Type-parten lyder som en ubrugelig). Du kan derefter læse indholdet i to dele: Læs først de første byte, der vil give dig størrelsen af ​​beskeden, og derefter læse meddelelsen af ​​dele, hvis du ikke vil overfylde hukommelsen.