简体   繁体   English

读写二维数组到文件

[英]Reading and writing two-dimensional array to file

I get a 2D array from a device at specific time intervals.我以特定的时间间隔从设备获取二维数组。 I keep these series in a list.我将这些系列放在一个列表中。 I need to write the sequences in the list to the file on the computer.我需要将列表中的序列写入计算机上的文件。 After reading these series I will put it in the list again.阅读完这些系列后,我将再次将其放入列表中。 I found a method for this.我找到了一种方法。 I can write the series.我可以写系列。 I have some questions at the point of reading.我在阅读时有一些问题。

When I write a fixed array;当我写一个固定的数组时; Example short[,] array2D = new short[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };示例short[,] array2D = new short[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };

I read it properly when I want to read the same series knowing its dimensions.当我想阅读同一系列知道它的尺寸时,我会正确阅读它。

But when I write more than one series in a row, I want to read it piece by piece.但是当我连续写多个系列时,我想逐个阅读。 I failed on this.我在这方面失败了。 How can I read the sequences from the file?如何从文件中读取序列?

Write Code编写代码

private void testWriteArray()
    {
        for (int i = 0; i<Globals.logArrayList.Count; i++)
        {
            array2D = Globals.logArrayList[i];

            FileStream writeStream = new FileStream(filename, FileMode.Append);
            BinaryWriter writeBinary = new BinaryWriter(writeStream);
            GCHandle arrHandle = GCHandle.Alloc(array2D, GCHandleType.Pinned);
            IntPtr arrPtr = arrHandle.AddrOfPinnedObject();

            unsafe
            {
                int arrLen = array2D.Length;
                if (arrLen > 0)
                {
                    IEnumerator enumerator = array2D.GetEnumerator();
                    enumerator.MoveNext();
                    int arrSize = System.Runtime.InteropServices.Marshal.SizeOf(enumerator.Current) * arrLen;

                    using (UnmanagedMemoryStream arrStream =
                    new UnmanagedMemoryStream((byte*)arrPtr.ToPointer(), arrSize))
                    {
                        arrStream.CopyTo(writeBinary.BaseStream, (int)arrStream.Length);
                    }
                }
            }

            arrHandle.Free();

            writeStream.Flush();
            writeStream.Close();

        }
    }

Read Code阅读代码

   static Array testReadArray()
    {

        int[,] array2D = new int[1000, 2000];

        FileStream readStream = new FileStream(filename, FileMode.Open);
        BinaryWriter readBinary = new BinaryWriter(readStream);
        GCHandle arrHandle = GCHandle.Alloc(array2D, GCHandleType.Pinned);
        IntPtr arrPtr = arrHandle.AddrOfPinnedObject();

        unsafe
        {
            int arrLen = array2D.Length;
            if (arrLen > 0)
            {
                IEnumerator enumerator = array2D.GetEnumerator();
                enumerator.MoveNext();
                int arrSize =
                System.Runtime.InteropServices.Marshal.SizeOf(enumerator.Current) * arrLen;

                using (UnmanagedMemoryStream arrStream = new UnmanagedMemoryStream
                ((byte*)arrPtr.ToPointer(), arrSize, arrSize, FileAccess.Write))
                {
                    readBinary.BaseStream.CopyTo(arrStream, (int)arrStream.Length);
                }
            }
        }

        arrHandle.Free();
        readStream.Close();
        return array2D;
    }

In the reading code, I don't know how many dimensions the array is in the file.在阅读代码中,我不知道该数组在文件中有多少维。 That's why I gave the array size 1000,2000.这就是我给数组大小 1000,2000 的原因。 Normally, although my data is between 0-255, I am reading 6-7 digit numbers while reading.通常,虽然我的数据在 0-255 之间,但我在阅读时正在阅读 6-7 位数字。

Is it possible for me to know the number of strings in the file?我可以知道文件中的字符串数吗? If so how?如果有怎么办?

This is not really an answer, but to show you another approach since you are using unsafe and know the size and dimensions of the array.这并不是真正的答案,而是向您展示另一种方法,因为您使用的是 unsafe 并且知道数组的大小和维度。 So I give you a minimal allocation, generic pointer span based constant multi dimensional multi array reader and writer所以我给你一个最小分配,基于通用指针跨度的常量多维多数组读取器和写入器

Given给定

public static unsafe void Write<T>(T[,] source, Stream stream) where T : unmanaged
{
   fixed (void* asd = source)
      stream.Write(new Span<byte>(asd, source.Length * sizeof(T)));
}
public static unsafe bool Read<T>(T[,] source, Stream stream) where T : unmanaged
{
   fixed (void* asd = source)
      return stream.Read(new Span<byte>(asd, source.Length * sizeof(T))) != 0;
}

The worlds most contrived example世界上最做作的例子

var array = new short[,] {{1, 2,}, {3, 4}, {5, 6}};

using (var rs = new FileStream(@"D:\test.dat", FileMode.Create))
   for (int i = 0; i < 10; i++)
   {
      array[0, 0] = (short) i; // to prove its working
      Write(array, rs);
      Console.WriteLine(string.Join(", ", array.Cast<short>()));
   }

Console.WriteLine();

using (var ws = new FileStream(@"D:\test.dat", FileMode.Open))
   while (Read(array, ws))
      Console.WriteLine(string.Join(", ", array.Cast<short>())); // to prove its working

Output Output

0, 2, 3, 4, 5, 6
1, 2, 3, 4, 5, 6
2, 2, 3, 4, 5, 6
3, 2, 3, 4, 5, 6
4, 2, 3, 4, 5, 6
5, 2, 3, 4, 5, 6
6, 2, 3, 4, 5, 6
7, 2, 3, 4, 5, 6
8, 2, 3, 4, 5, 6
9, 2, 3, 4, 5, 6

0, 2, 3, 4, 5, 6
1, 2, 3, 4, 5, 6
2, 2, 3, 4, 5, 6
3, 2, 3, 4, 5, 6
4, 2, 3, 4, 5, 6
5, 2, 3, 4, 5, 6
6, 2, 3, 4, 5, 6
7, 2, 3, 4, 5, 6
8, 2, 3, 4, 5, 6
9, 2, 3, 4, 5, 6

Note : you can modify this to create and return an array.注意:您可以修改它以创建并返回一个数组。 however this was just a low allocation version that can reuse an array然而,这只是一个可以重用数组的低分配版本

Note : if you just write 2 ints before the array, you can read any size array and any amount packets注意:如果你只是在数组前写 2 个整数,你可以读取任意大小的数组和任意数量的数据包

The problem was so simple that I don't know how I missed it.问题太简单了,我不知道我是怎么错过的。 The array type I defined during reading is integer , but my data is short .我在阅读时定义的数组类型是integer ,但我的数据很short When the data type of the array was short the whole problem was gone.当数组的数据类型很short ,整个问题就消失了。

I also solved the total number of sequences in the file as follows.我还解决了文件中的序列总数,如下所示。

The lengths of the 2-dimensional array at the time of writing are 48 * 64. I divided the total number of bytes in the file by 48 * 64. Also, since my data is short ( 2 bytes ) I divided it by 2 to get the total number of strings.编写时二维数组的长度为 48 * 64。我将文件中的总字节数除以 48 * 64。另外,由于我的数据很short2 bytes ),我将其除以 2获取字符串的总数。

var arrayCount = readBinary.BaseStream.Length / (48*64) / 2;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM