6

さまざまな種類のアーカイブで動作する必要があるアプリを開発しています。できるだけ多くのアーカイブ タイプが適切です。archive-worker のエンジンとして 7zip.dll を選択しました。しかし、問題があります.アーカイブからメモリバッファにファイルを解凍する方法を知っている人はいますか? ご覧のとおり、7zip.dll はハードディスクへの解凍のみをサポートしています。また、メモリ バッファからアーカイブをロードするとよいでしょう。誰かがそのようなことをしようとしたことがありますか?

4

1 に答える 1

2

あなたのニーズを完全に理解しているかどうかわかりません (たとえば、ディスク上の圧縮解除されたファイルは必要ありませんか?)。

LZMA SDK 9.20とそのlzma.txt readme ファイルを見ていましたが、メモリへの解凍が可能であるというヒントがたくさんあります。C++ インターフェイスではなく C API を使用する必要があるだけかもしれません。たとえば、次のセクションを確認してくださいSingle-call Decompressing

When to use: RAM->RAM decompressing
Compile files: LzmaDec.h + LzmaDec.c + Types.h
Compile defines: no defines
Memory Requirements:
  - Input buffer: compressed size
  - Output buffer: uncompressed size
  - LZMA Internal Structures: state_size (16 KB for default settings)

また、次の機能があります。

SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);

これらは、アーカイブ ファイルをメモリ マッピングすることで利用できます。私の知る限りでは、プロセスが排他的アクセスでメモリ マップト ファイルを作成し (他のプロセスがアクセスできないようにする)、明示的なフラッシュを行わない場合、ファイルへのすべての変更は、マッピングが破棄されるか、または破棄されるまでメモリに保持されます。ファイルを閉じました。または、アーカイブの内容をメモリにロードすることもできます。

完全を期すために、いくつかの例をハックして、Windows でメモリ マッピングを使用するデモを作成しました。

#include <stdio.h>
#include <time.h>
#include <Windows.h>
#include <WinNT.h>

// This demo will limit the file to 4KiB
#define FILE_SIZE_MAX_LOWER_DW 4096
#define FILE_SIZE_MAX_UPPER_DW 0
#define MAP_OFFSET_LOWER_DW 0
#define MAP_OFFSET_UPPER_DW 0
#define TEST_ITERATIONS 1000
#define INT16_SIZE 2

typedef short int int16;

// NOTE: This will not work for Windows less than XP or 2003 Server!
int main()
{
    HANDLE  hFile, hFileMapping;
    PBYTE mapViewStartAddress;
    // Note: with no explicit security attributes, the process needs to have
    // the necessary rights (e.g. read, write) to this location.
    LPCSTR path = "C:\\Users\\mcmlxxxvi\\Desktop\\test.dat";

    // First, open a file handle.
    hFile = CreateFile(path,
                       GENERIC_READ | GENERIC_WRITE,    // The file is created with Read/Write permissions
                       FILE_SHARE_READ,                 // Set this to 0 for exclusive access
                       NULL,                            // Optional security attributes
                       CREATE_ALWAYS,                   // File is created if not found, overwritten otherwise
                       FILE_ATTRIBUTE_TEMPORARY,        // This affects the caching behaviour
                       0);                              // Attributes template, can be left NULL
    if ((hFile) == INVALID_HANDLE_VALUE)
    {
        fprintf(stderr, "Unable to open file");
        return 1;
    }

    // Then, create a memory mapping for the opened file.
    hFileMapping = CreateFileMapping(hFile,                     // Handle for an opened file
                                     NULL,                      // Optional security attributes
                                     PAGE_READWRITE,            // File can be mapped for Read/Write access
                                     FILE_SIZE_MAX_UPPER_DW,    // Maximum file size split in DWORDs.
                                     FILE_SIZE_MAX_LOWER_DW,    // NOTE: I may have these two mixed up!
                                     NULL);                     // Optional name
    if (hFileMapping == 0)
    {
        CloseHandle(hFile);
        fprintf(stderr, "Unable to open file for mapping.");
        return 1;
    }

    // Next, map a view (a continuous portion of the file) to a memory region
    // The view must start and end at an offset that is a multiple of
    // the allocation granularity (roughly speaking, the machine page size).
    mapViewStartAddress = (PBYTE)MapViewOfFile(hFileMapping,                    // Handle to a memory-mapped file
                                               FILE_MAP_READ | FILE_MAP_WRITE,  // Maps the view for Read/Write access
                                               MAP_OFFSET_UPPER_DW,             // Offset in the file from which
                                               MAP_OFFSET_LOWER_DW,             // the view starts, split in DWORDs.
                                               FILE_SIZE_MAX_LOWER_DW);         // Size of the view (here, entire file)
    if (mapViewStartAddress == 0)
    {
        CloseHandle(hFileMapping);
        CloseHandle(hFile);
        fprintf(stderr, "Couldn't map a view of the file.");
        return 1;
    }

    // This is where actual business stuff belongs.
    // This example application does iterations of reading and writing
    // random numbers for the entire length of the file.

    int16 value;
    errno_t result = 0;

    srand((int)time(NULL));
    for (int i = 0; i < TEST_ITERATIONS; i++)
    {
        // Write
        for (int j = 0; j < FILE_SIZE_MAX_LOWER_DW / INT16_SIZE; j++)
        {
            value = rand();
            result = memcpy_s(mapViewStartAddress + j * INT16_SIZE, INT16_SIZE, &value, INT16_SIZE); 
            if (result != 0)
            {
                CloseHandle(hFileMapping);
                CloseHandle(hFile);
                fprintf(stderr, "File write error during iteration #%d, error %d", i, GetLastError());
                return 1;
            }
        }
        // Read
        SetFilePointer(hFileMapping, 0, 0, FILE_BEGIN);
        for (int j = 0; j < FILE_SIZE_MAX_LOWER_DW / sizeof(int); j++)
        {
            result = memcpy_s(&value, INT16_SIZE, mapViewStartAddress + j * INT16_SIZE, INT16_SIZE);
            if (result != 0)
            {
                CloseHandle(hFileMapping);
                CloseHandle(hFile);
                fprintf(stderr, "File read error during iteration #%d, error %d", i, GetLastError());
                return 1;
            }
        }
    }

    // End business stuff

    CloseHandle(hFileMapping);
    CloseHandle(hFile);

    return 0;
}
于 2012-08-24T16:17:39.217 に答える