Menu

extract file into memory using 7z.dll

estux
2013-07-10
2015-04-14
  • estux

    estux - 2013-07-10

    Hi,

    I am trying to modify the CArchiveExtractCallback class from the Client7z to get files extracted into memory.

    I suppose that the relevant part of code is:

    _outFileStreamSpec = new COutFileStream;
    CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
    if (!_outFileStreamSpec->Open(fullProcessedPath, CREATE_ALWAYS))
    {
      PrintString((UString)L"can not open output file " + fullProcessedPath);
      return E_ABORT;
    }
    _outFileStream = outStreamLoc;
    *outStream = outStreamLoc.Detach();
    

    I think that I should use COutMemStream instead of COutFileStream, but I have no idea about what is the right way to use it. Is there any code sample?

    The idea is extract a single file (f.e: file at index 3), and after the extraction is finished get the raw data from CArchiveExtractCallback.

    Thanks

     
  • Igor Pavlov

    Igor Pavlov - 2013-07-11

    If unpackSize is known, you can use CBufPtrSeqOutStream:

    CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream;
    CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
    outStreamSpec->Init(data, unpackSize);

    If unpackSize is unknown (gzip, bzip2), you can use CDynBufSeqOutStream.

     
  • estux

    estux - 2013-07-11

    Thank you so much Igor, now it is working fine.

     
  • undefauth

    undefauth - 2013-09-19

    I'm trying to do the same thing, I was just wondering, where exactly is this "data" that is used with Init()?

    Thanks.

     
  • Igor Pavlov

    Igor Pavlov - 2013-09-20

    You must allocate buffer for uncompressed data.
    The "data" is a pointer to that buffer.

     
  • undefauth

    undefauth - 2013-09-23

    I realized thats what I must do, don't know what I was thinking. Thanks so much for the reply.

     
  • ak24

    ak24 - 2015-04-10

    I'm too trying to extract the file to buffer...but how the decompressed data is filled in the buffer before/after calling outStreamSpec->Init(data, unpackSize);

     
  • ak24

    ak24 - 2015-04-14

    Thanks.
    With CoutFileStream there was no call back from 7z.dll when call to extract was made from Client7z.
    Simply change the name of COutFileStream to CBufPtrSeqOutStream to get the stream . COutFileStream is a class declared in FileStreams.h. When CArchiveExtractCallback::GetStream is call backed from 7z.dll GetStream returns In/Out param as ISequentialOutStream** which should point to concrete implementation of CBufPtrSeqOutStream. Implement ISequentialOutStream::Write(. . . ) as per your need.

    STDMETHODIMP CBufPtrSeqOutStream::Write(const void data, UInt32 size, UInt32 processedSize)
    {
    UInt32 realProcessedSize;
    bool result = File.WritePart(data, size, realProcessedSize); //Don't call this if

    // data is not required to be written on disk. but make sure realProcessedSize is correct

    // otherwise it would be recursive loop
    Byte buffer = new Byte[size];
    memcpy(buffer, data, size); //copy data to buffer
    ProcessedSize += realProcessedSize;
    if (processedSize)
    processedSize = realProcessedSize;
    return ConvertBoolToHRESULT(result);
    }

     

Log in to post a comment.