0

私のアプリケーションでは、いくつかのXMLファイルから作成されたかなり大きなオブジェクトがあります。xmlファイルのサイズは30MBのようなもので、このxmlファイルのバイナリシリアル化オブジェクトは8〜9MBのようになります。面白いことに、このバイナリファイルをWinRarなどで圧縮すると、1〜2MBになります。

オブジェクト自体の圧縮レベルを上げる方法はありますか?または、保存後にファイルを圧縮するコードを手動で作成するか、プログラムにロードする前に解凍して、別のレベルの圧縮を使用する必要がありますか?

場合、これはオブジェクトをファイルとして保存するために使用するコードです。

    public static bool SaveProject(Project proj, string pathAndName)
    {
        bool success = true;
        proj.FileVersion = CurrentFileVersion;

        try
        {
            IFormatter formatter = new BinaryFormatter();
            Stream stream = new FileStream(pathAndName, FileMode.Create, FileAccess.Write, FileShare.None);
            formatter.Serialize(stream, proj);
            stream.Close();
        }
        catch (Exception e)
        {
            MessageBox.Show("Can not save project!" + Environment.NewLine + "Reason: ", "Error",
                            MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

            success = false;
        }

        return success;
    }

UPDATE を追加してコードを変更しようとしましたGZIPSTREAMが、何も実行されないようです。それとも私の実装が間違っていますか?

public static bool SaveProject(Project proj, string pathAndName)
{
    bool success = true;
    proj.FileVersion = CurrentFileVersion;

    try
    {
        IFormatter formatter = new BinaryFormatter();
        var stream = new FileStream(pathAndName, FileMode.Create, FileAccess.Write, FileShare.None);
        var gZipStream = new GZipStream(stream, CompressionMode.Compress);
        formatter.Serialize(stream, proj);
        stream.Close();
        gZipStream.Close();
    }
    catch (Exception e)
    {
        MessageBox.Show("Can not save project!" + Environment.NewLine + "Reason: ", "Error",
                        MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

        success = false;
    }

    return success;
}

public static Project LoadProject(string path)
{
    IFormatter formatter = new BinaryFormatter();
    Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
    var gZipStream = new GZipStream(stream, CompressionMode.Decompress);
    var obj = (Project)formatter.Deserialize(gZipStream);
    stream.Close();
    gZipStream.Close();

    if (obj.FileVersion != CurrentFileVersion)
    {
        throw new InvalidFileVersionException("File version belongs to an older version of the program.");
    }

    return obj;
}
4

1 に答える 1

5

with でラップFileStreamして、それをシリアライザに渡します。次に、デシリアライズするには、 aを でラップします。DeflateStreamCompressionMode.CompressFileStreamDeflateStreamCompressionMode.Decompress

Close明示的に呼び出す代わりに、usingステートメントを使用する必要があることに注意してください。

using (FileStream fileStream = ...)
using (DeflateStream deflateStream = new DeflateStream(fileStream, 
                                                      CompressionMode.Compress))
{
    formatter.Serialize(deflateStream, proj);
}

同じ方法で使用できますGZipStream- 両方を試して、どちらがより良い圧縮をもたらす傾向があるかを確認してください (または、それが気になる場合はパフォーマンスが向上します)。

このアプローチがシリアライゼーションの側面を圧縮の側面からどのように分離しているかに注目してください。シリアル化コードは、データに何が起こるかを気にせずにストリームに書き込むだけであり、圧縮コードは、データが何を意味するかを気にせずに、与えられたものを圧縮するだけです。

于 2012-08-24T09:19:55.383 に答える