在 C# 中从磁盘读取短数组的最佳方法?



我必须将 4GB 的 short[] 数组写入磁盘和从磁盘写入 4GB 的 short[] 数组,所以我找到了一个函数来写入数组,并且我正在努力编写代码以从磁盘读取数组。我通常用其他语言编码,所以如果我的尝试到目前为止有点可怜,请原谅我:

using UnityEngine;
using System.Collections;
using System.IO;
public class RWShort : MonoBehaviour {
public static void WriteShortArray(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);
}
}
}
} //Above is fine, here is where I am confused: 

public static short[] ReadShortArray(string path) 
{
byte[]  thisByteArray= File.ReadAllBytes(fileName);
short[] thisShortArray= new short[thisByteArray.length/2];      
for (int i = 0; i < 10; i+=2)
{
thisShortArray[i]= ? convert from byte array;
}

return thisShortArray;
}   
}

短裤是两个字节,所以每次必须读取两个字节。我还建议使用这样的yield return,这样您就不会尝试一次性将所有内容拉入内存中。虽然如果你需要所有的短裤在一起,那对你没有帮助..我猜这取决于你用它做什么。

void Main()
{
short[] values = new short[] {
1, 999, 200, short.MinValue, short.MaxValue
};
WriteShortArray(values, @"C:tempshorts.txt");
foreach (var shortInfile in ReadShortArray(@"C:tempshorts.txt"))
{
Console.WriteLine(shortInfile);
}
}
public static void WriteShortArray(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);
}
}
}
}
public static IEnumerable<short> ReadShortArray(string path)
{
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
using (BinaryReader br = new BinaryReader(fs))
{
byte[] buffer = new byte[2];
while (br.Read(buffer, 0, 2) > 0)
yield return (short)(buffer[0]|(buffer[1]<<8)); 
}
}

您也可以这样定义它,利用BinaryReader

public static IEnumerable<short> ReadShortArray(string path)
{
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
using (BinaryReader br = new BinaryReader(fs))
{
while (br.BaseStream.Position < br.BaseStream.Length)
yield return br.ReadInt16();
}
}

内存映射文件是你的朋友,有一个MemoryMappedViewAccessor.ReadInt16函数,允许你直接从操作系统磁盘缓存中读取类型为short的数据。 也是一个接受Int16Write()重载。 如果要调用需要传统 .NET 数组的函数,还要ReadArrayWriteArray函数。

在 MSDN 上的 .NET 中使用内存映射文件概述

如果要使用普通文件I/O执行此操作,请使用1或2兆字节的块大小和Buffer.BlockCopy函数在byte[]short[]之间批量移动数据,并使用接受byte[]FileStream函数。 忘记BinaryWriterBinaryReader,忘记一次做2个字节。

也可以在 p/invoke 的帮助下将 I/O 直接执行到 .NET 数组中,请参阅我使用ReadFile的答案并在此处传递FileStream对象的SafeFileHandle属性 但是即使它没有额外的副本,它仍然不应该跟上内存映射ReadArrayWriteArray调用。

最新更新