zeroshi
zeroshi

Reputation: 129

How can i create an accurate output buffer in C++ for 7zip command line output?

I originally used GetFileSize() and then found out that is not the correct way to go. Please give me some suggestions.

Upvotes: 0

Views: 566

Answers (2)

seva titov
seva titov

Reputation: 11920

When you launch a process, you will get an output stream (assuming you have redirected its standard output). A proper way of dealing with streams is to read it by chunks, multiple times untill you reach end of the stream. A sample code is on MSDN page -- look for function ReadFromPipe(void). Here is the copy of the code:

void ReadFromPipe(void) 

// Read output from the child process's pipe for STDOUT
// and write to the parent process's pipe for STDOUT. 
// Stop when there is no more data. 
{ 
   DWORD dwRead, dwWritten; 
   CHAR chBuf[BUFSIZE]; 
   BOOL bSuccess = FALSE;
   HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE);

   for (;;) 
   { 
      bSuccess = ReadFile( g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);
      if( ! bSuccess || dwRead == 0 ) break; 

      // ... -> do your processing here.
   } 
} 

If you do need to aggregate the entire stream into one buffer, you can use dynamically allocated containers, e.g. std::vector, std::string, std::list, etc.

Upvotes: 1

rivimey
rivimey

Reputation: 931

I assume what you mean by "output buffer" is a chunk of memory used to receive the uncompressed file from a 7z file decompression. You aren't clear on this though.

I would encourage you to try streaming the output, if you can, rather than grab it all at once. This way you won't have to know what the size is. The standard 7-Zip LZMA SDK provides a zlib compatible API for doing this which makes streaming compression or decompression relatively easy.

If this is impossible for some reason, you will have to do it in two stages: I believe the 7z archive format stores the original file size as well as the compressed size, so asking for the table-of-contents entry for the file in question should return the original size and you can allocate that as the buffer.

If you are really piping from some source, so you are just seeing a stream of bytes being passed through a 7z compress or decompress action, the likelyhood is that there is no size information available... and you will just have to work around that. However, you did say you tried GetFileSize() which suggests there is a file of some sort so hopefully that isn't the problem you face.

HtH

Ruth

Upvotes: 3

Related Questions