¿Cuál es la mejor manera de escribir una matriz corta [] en un archivo en C #?

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

  •  03-07-2019
  •  | 
  •  

Pregunta

Tengo una serie de cortos (cortos []) que necesito escribir en un archivo. ¿Cuál es la forma más rápida de hacer esto?

¿Fue útil?

Solución

Usa el 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);
                }
            }
        }
    }

Otros consejos

Siguiendo con la respuesta de Jon B, si su archivo contiene otros datos, es posible que desee prefijar los datos con el recuento de valores.

es decir:

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);
            }
        }
    }
}

BinaryFormatter de hecho es 10 veces más rápido tanto para lecturas como para escrituras cuando se usa con matrices de tipos primitivos (obj.GetType (). IsPrimitive), es decir, no para Decimal y String (que no son primitivos) y ciertamente no para ninguna otra estructura o clase donde, en cambio, es terriblemente lento.

[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);
  }
}

Salida:

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

Entonces, use BinaryFormatter siempre que tenga una matriz de un tipo primitivo, o una matriz de matrices pero no matrices de atenuación múltiple (!). Si su tipo de datos es, por ejemplo, Point3 (doble), debe llenar un doble [] y serializarlo en su lugar. Solo use BinaryWriter para tipos complejos / mixtos, cadenas, decimales y valores singulares.

Al tratar con el byte [], BinaryFormatter y BinaryWriter tienen el mismo rendimiento (y son muy rápidos). Si puede convertir su tipo a byte-array de una manera efectiva, puede obtener un rendimiento aún más rápido de esta manera.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top