データをバイナリにシリアル化してディスクに書き込むC#で記述されたプログラムがあります。このファイルにさらにデータを追加したい場合は、最初にファイル全体を逆シリアル化してから、さらにシリアル化されたデータを追加する必要があります。既存のデータを逆シリアル化せずにこのシリアル化されたファイルにデータを追加して、プロセス全体の時間を節約することはできますか?
1789 次
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
/ DataSet
viaについて話していることがわかったので(コメント)、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 に答える