簡體   English   中英

讀寫二維數組到文件

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

我以特定的時間間隔從設備獲取二維數組。 我將這些系列放在一個列表中。 我需要將列表中的序列寫入計算機上的文件。 閱讀完這些系列后,我將再次將其放入列表中。 我找到了一種方法。 我可以寫系列。 我在閱讀時有一些問題。

當我寫一個固定的數組時; 示例short[,] array2D = new short[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };

當我想閱讀同一系列知道它的尺寸時,我會正確閱讀它。

但是當我連續寫多個系列時,我想逐個閱讀。 我在這方面失敗了。 如何從文件中讀取序列?

編寫代碼

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

        }
    }

閱讀代碼

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

在閱讀代碼中,我不知道該數組在文件中有多少維。 這就是我給數組大小 1000,2000 的原因。 通常,雖然我的數據在 0-255 之間,但我在閱讀時正在閱讀 6-7 位數字。

我可以知道文件中的字符串數嗎? 如果有怎么辦?

這並不是真正的答案,而是向您展示另一種方法,因為您使用的是 unsafe 並且知道數組的大小和維度。 所以我給你一個最小分配,基於通用指針跨度的常量多維多數組讀取器和寫入器

給定

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

世界上最做作的例子

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

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

注意:您可以修改它以創建並返回一個數組。 然而,這只是一個可以重用數組的低分配版本

注意:如果你只是在數組前寫 2 個整數,你可以讀取任意大小的數組和任意數量的數據包

問題太簡單了,我不知道我是怎么錯過的。 我在閱讀時定義的數組類型是integer ,但我的數據很short 當數組的數據類型很short ,整個問題就消失了。

我還解決了文件中的序列總數,如下所示。

編寫時二維數組的長度為 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