C#からC ++からのzlib(ストリーミングと[]バイトをストリーミングするために[]バイトを変換する方法)

StackOverflow https://stackoverflow.com/questions/737258

  •  09-09-2019
  •  | 
  •  

質問

私のタスクは、ZLIBを用いて(受信)パケットを解凍した後、データから画像を作るためにそのアルゴリズムを使用することである

良いニュースは、私はC ++のコードを持っているということですが、タスクは、C#でそれを行うことです。

C ++

        //Read the first values of the packet received

        DWORD image[200 * 64] = {0}; //used for algoritm(width always = 200 and height always == 64)
        int imgIndex = 0; //used for algoritm
        unsigned char rawbytes_[131072] = {0}; //read below
        unsigned char * rawbytes = rawbytes_; //destrination parameter for decompression(ptr)
        compressed = r.Read<WORD>(); //the length of the compressed bytes(picture)
        uncompressed = r.Read<WORD>(); //the length that should be after decompression
        width = r.Read<WORD>(); //the width of the picture
        height = r.Read<WORD>(); //the height of the picture

        LPBYTE ptr = r.GetCurrentStream(); //the bytes(file that must be decompressed)

        outLen = uncompressed; //copy the len into another variable

        //Decompress

        if(uncompress((Bytef*)rawbytes, &outLen, ptr, compressed) != Z_OK)
        {
            printf("Could not uncompress the image code.\n");
            Disconnect();
            return;
        }

        //Algoritm to make up the picture
        // Loop through the data
        for(int c = 0; c < (int)height; ++c)
        {
            for(int r = 0; r < (int)width; ++r)
            {
                imgIndex = (height - 1 - c) * width + r;
                image[imgIndex] = 0xFF000000;
                if(-((1 << (0xFF & (r & 0x80000007))) & rawbytes[((c * width + r) >> 3)])) 
                    image[imgIndex] = 0xFFFFFFFF;
            }
        }

私はzlib.NETでこれをやろうとしているが、すべてのデモを解凍するために、そのコード(C#)を持っている。

    private void decompressFile(string inFile, string outFile)
    {
        System.IO.FileStream outFileStream = new System.IO.FileStream(outFile, System.IO.FileMode.Create);
        zlib.ZOutputStream outZStream = new zlib.ZOutputStream(outFileStream);
        System.IO.FileStream inFileStream = new System.IO.FileStream(inFile, System.IO.FileMode.Open);          
        try
        {
            CopyStream(inFileStream, outZStream);
        }
        finally
        {
            outZStream.Close();
            outFileStream.Close();
            inFileStream.Close();
        }
    }

    public static void CopyStream(System.IO.Stream input, System.IO.Stream output)
    {
        byte[] buffer = new byte[2000];
        int len;
        while ((len = input.Read(buffer, 0, 2000)) > 0)
        {
            output.Write(buffer, 0, len);
        }
        output.Flush();
    }

私の問題:私はC ++コードに示したそのアルゴリズムを使用する必要があるため、私は、解凍後のファイルを保存しない

バックバイト配列にストリームを変換する方法、データを解凍し、ためにC#のzlibのコード内の1へのストリームの似にバイト[]配列に変換するには?

また、ファイルを保存しないためにzlib.NETコードを変更するには?

役に立ちましたか?

解決

だけではなく、ファイルストリームのMemoryStreamsを使用します:

// Assuming inputData is a byte[]
MemoryStream input = new MemoryStream(inputData);
MemoryStream output = new MemoryStream();

そして、あなたはバイト配列を取得するには、その後output.ToArray()を使用することができます。

別段usingへの最初の呼び出しが失敗した場合、残りは行われません -

ではなく、単一のtry / finallyブロックのClose文を使用することが一般的により良いということに注意してください。あなたが巣彼らがこれを好きなことができます:

using (MemoryStream output = new MemoryStream())
using (Stream outZStream = new zlib.ZOutputStream(output))
using (Stream input = new MemoryStream(bytes))
{
    CopyStream(inFileStream, outZStream);
    return output.ToArray();
}

他のヒント

私はこの同じ問題に遭遇します。

、完全性のために...(これは数時間のために私を困惑させているため)。

あなたがoutput.ToArray()を返す呼び出す前に、

ZLib.Netの場合、あなたはまた、)通常(閉じる時に発生した仕上がりを()、呼び出す必要があります。

ZStreamは、実際にはまだ、すべてのデータを書き込んでいないので、それ以外の場合は、あなたが、あなたのメモリストリームから空/不完全なバイト配列を取得します。

public static void CompressData(byte[] inData, out byte[] outData)
{
    using (MemoryStream outMemoryStream = new MemoryStream())
    using (ZOutputStream outZStream = new ZOutputStream(outMemoryStream, zlibConst.Z_DEFAULT_COMPRESSION))
    using (Stream inMemoryStream = new MemoryStream(inData))
    {
        CopyStream(inMemoryStream, outZStream);
        outZStream.finish();
        outData = outMemoryStream.ToArray();
    }
}

public static void DecompressData(byte[] inData, out byte[] outData)
{
    using (MemoryStream outMemoryStream = new MemoryStream())
    using (ZOutputStream outZStream = new ZOutputStream(outMemoryStream))
    using (Stream inMemoryStream = new MemoryStream(inData))
    {
        CopyStream(inMemoryStream, outZStream);
        outZStream.finish();
        outData = outMemoryStream.ToArray();
    }
}

この例では、私はまた、zlibの名前空間を使用しています:

using zlib;

もともとこのスレッドで見つかりました: ZLIB解凍する

私はまだアップ投票する十分なポイントを持っていないので...

てToArray前に仕上げに関する先端ためのティム・グリーブスのおかげで、

そしてジョンスキート

(私は最終的に/試みるよりもはるかに良い好き)ストリームのusingステートメントをネストに関するヒントについて
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top