5

データをバイナリにシリアル化してディスクに書き込むC#で記述されたプログラムがあります。このファイルにさらにデータを追加したい場合は、最初にファイル全体を逆シリアル化してから、さらにシリアル化されたデータを追加する必要があります。既存のデータを逆シリアル化せずにこのシリアル化されたファイルにデータを追加して、プロセス全体の時間を節約することはできますか?

4

2 に答える 2

3

データを追加するためにファイル内のすべてのデータを読み取る必要はありません。

追加モードで開いてデータを書き込むことができます。

var fileStream = File.Open(fileName, FileMode.Append, FileAccess.Write, FileShare.Read);
var binaryWriter = new BinaryWriter(fileStream);
binaryWriter.Write(data);
于 2012-07-16T06:52:48.607 に答える
2

DataTable/ DataSetviaについて話していることがわかったので(コメント)、BinaryFormatterより明確になります。それが既存のテーブルに余分な行として表示されることを意図している場合は、いいえ:それは機能しません。あなたができることは追加することですが、各テーブルを順番に逆シリアル化し、次にコンテンツを手動でマージします。それはおそらくあなたが説明することであなたの最善の策です。これは2を使用した例ですが、明らかにEOFまで逆シリアル化/マージを繰り返します。

var dt = new DataTable();
dt.Columns.Add("foo", typeof (int));
dt.Columns.Add("bar", typeof(string));

dt.RemotingFormat = SerializationFormat.Binary;
var ser = new BinaryFormatter();
using(var ms = new MemoryStream())
{
    dt.Rows.Add(123, "abc");
    ser.Serialize(ms, dt); // batch 1
    dt.Rows.Clear();
    dt.Rows.Add(456, "def");
    ser.Serialize(ms, dt); // batch 2

    ms.Position = 0;

    var table1 = (DataTable) ser.Deserialize(ms);

    // the following is the merge loop that you'd repeat until EOF
    var table2 = (DataTable) ser.Deserialize(ms);
    foreach(DataRow row in table2.Rows) {
        table1.ImportRow(row);
    }

    // show the results
    foreach(DataRow row in table1.Rows)
    {
        Console.WriteLine("{0}, {1}", row[0], row[1]);
    }
}

でも!DataTable個人的に私はとの両方について不安を持っていBinaryFormatterます。データが何であるかを知っている場合は、他の手法があります。たとえば、protobufは本質的に追加可能であるため、これは「protobuf」を使用して非常に簡単に実行できます。実際、追加しないように追加の作業を行う必要があります(これも十分に単純ですが)。

[ProtoContract]
class Foo
{
    [ProtoMember(1)]
    public int X { get; set; }
    [ProtoMember(2)]
    public string Y { get; set; }

}
[ProtoContract]
class MyData
{
    private readonly List<Foo> items = new List<Foo>();
    [ProtoMember(1)]
    public List<Foo> Items { get { return items; } }
}

それから:

var batch1 = new MyData { Items = { new Foo { X = 123, Y = "abc" } } };
var batch2 = new MyData { Items = { new Foo { X = 456, Y = "def" } } };
using(var ms = new MemoryStream())
{
    Serializer.Serialize(ms, batch1);
    Serializer.Serialize(ms, batch2);
    ms.Position = 0;
    var merged = Serializer.Deserialize<MyData>(ms);
    foreach(var row in merged.Items) {
        Console.WriteLine("{0}, {1}", row.X, row.Y);
    }
}
于 2012-07-16T08:46:07.290 に答える