6

我有一个短裤数组(short []),我需要写出一个文件。最快的方法是什么?

4

3 回答 3

12

使用 BinaryWriter

    static void WriteShorts(short[] values, string path)
    {
        using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
        {
            using (BinaryWriter bw = new BinaryWriter(fs))
            {
                foreach (short value in values)
                {
                    bw.Write(value);
                }
            }
        }
    }
于 2008-10-22T02:19:20.850 回答
2

跟进 Jon B 的回答,如果您的文件包含任何其他数据,您可能希望在数据前面加上值的计数。

IE:

static void WriteShorts(short[] values, string path)
{
    using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
    {
        using (BinaryWriter bw = new BinaryWriter(fs))
        {
            // Write the number of items
            bw.Write(values.Length);

            foreach (short value in values)
            {
                bw.Write(value);
            }
        }
    }
}
于 2008-10-22T02:28:01.347 回答
1

BinaryFormatter实际上在与原始类型数组 (obj.GetType().IsPrimitive) 一起使用时的读取和写入速度快了大约 10 倍,即不适用于 Decimal 和 String(它们不是原始类型),当然也不适用于任何其他结构或相反,它的速度非常慢。

[Test]
public void TestShortArray()
{
  var n = 100000000;
  var input = new short[n];
  var r = new Random();
  for (var i = 0; i < n; i++) input[i] = (short)r.Next();
  var bf = new BinaryFormatter();
  var sw = new Stopwatch();
  using (var ms = new MemoryStream())
  {
    sw.Start();
    bf.Serialize(ms, input);
    sw.Stop();
    Console.WriteLine("BinaryFormatter serialize: " +
      sw.ElapsedMilliseconds + " ms, " + ms.ToArray().Length + " bytes");
    sw.Reset();
    ms.Seek(0, SeekOrigin.Begin);
    sw.Start();
    var output = (short[])bf.Deserialize(ms);
    sw.Stop();
    Console.WriteLine("BinaryFormatter deserialize: " +
      sw.ElapsedMilliseconds + " ms, " + ms.ToArray().Length + " bytes");
    Assert.AreEqual(input, output);
  }
  sw.Reset();
  using (var ms = new MemoryStream())
  {
    var bw = new BinaryWriter(ms, Encoding.UTF8, true);
    sw.Start();
    bw.Write(input.Length);
    for (var i = 0; i < input.Length; i++) bw.Write(input[i]);
    sw.Stop();
    Console.WriteLine("BinaryWriter serialize: " +
      sw.ElapsedMilliseconds + " ms, " + ms.ToArray().Length + " bytes");
    sw.Reset();
    ms.Seek(0, SeekOrigin.Begin);
    var br = new BinaryReader(ms, Encoding.UTF8, true);
    sw.Start();
    var length = br.ReadInt32();
    var output = new short[length];
    for (var i = 0; i < length; i++) output[i] = br.ReadInt16();
    sw.Stop();
    Console.WriteLine("BinaryReader deserialize: " +
      sw.ElapsedMilliseconds + " ms, " + ms.ToArray().Length + " bytes");
    Assert.AreEqual(input, output);
  }
}

输出:

BinaryFormatter serialize: 175 ms, 200000028 bytes
BinaryFormatter deserialize: 79 ms, 200000028 bytes
BinaryWriter serialize: 1499 ms, 200000004 bytes
BinaryReader deserialize: 1599 ms, 200000004 bytes

因此,只要您有原始类型的数组或数组数组但没有多维数组(!),请使用 BinaryFormatter。如果您的数据类型是例如 Point3(double) 您应该填写一个 double[] 并将其序列化。仅将 BinaryWriter 用于复杂/混合类型、字符串、小数和奇异值。

在处理 byte[] 时,BinaryFormatter 和 BinaryWriter 的性能相同(而且速度非常快)。如果您能以有效的方式将您的类型转换为字节数组,您可能会通过这种方式获得更快的性能。

于 2017-03-20T15:11:41.087 回答