读写二维数组到文件
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位的数字。
我可以知道文件中的字符串数量吗?如果有怎么办?
这个问题太简单了,我都不知道我是怎么漏掉的。我在阅读时定义的数组类型是integer
,但我的数据是short
。当数组的数据类型为 short
时,整个问题就消失了。
我还解决了文件中的序列总数如下。
写的时候二维数组的长度是48*64,我把文件的总字节数除以48*64。另外,由于我的数据是short
( 2 bytes
) 我把它除以 2 得到字符串的总数。
var arrayCount = readBinary.BaseStream.Length / (48*64) / 2;
这并不是真正的答案,而是向您展示另一种方法,因为您使用的是不安全的并且知道数组的大小和维数。所以我给你一个最小分配,基于通用指针跨度的常量多维多数组reader和writer
给定
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
输出
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
注意 :您可以修改它以创建和 return 一个数组。然而,这只是一个可以重用数组的低分配版本
注意:如果你在数组前写2个整数,你可以读取任意大小的数组和任意数量的数据包
我在特定时间间隔从设备获取二维数组。我将这些系列列在一个列表中。我需要将列表中的序列写入计算机上的文件中。读完这些系列后 我会把它再次放在列表中。我找到了一个方法。我可以写这个系列。我在阅读的时候有一些疑问。
当我写一个固定数组时;示例 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位的数字。
我可以知道文件中的字符串数量吗?如果有怎么办?
这个问题太简单了,我都不知道我是怎么漏掉的。我在阅读时定义的数组类型是integer
,但我的数据是short
。当数组的数据类型为 short
时,整个问题就消失了。
我还解决了文件中的序列总数如下。
写的时候二维数组的长度是48*64,我把文件的总字节数除以48*64。另外,由于我的数据是short
( 2 bytes
) 我把它除以 2 得到字符串的总数。
var arrayCount = readBinary.BaseStream.Length / (48*64) / 2;
这并不是真正的答案,而是向您展示另一种方法,因为您使用的是不安全的并且知道数组的大小和维数。所以我给你一个最小分配,基于通用指针跨度的常量多维多数组reader和writer
给定
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
输出
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
注意 :您可以修改它以创建和 return 一个数组。然而,这只是一个可以重用数组的低分配版本
注意:如果你在数组前写2个整数,你可以读取任意大小的数组和任意数量的数据包