在 C# 中从磁盘读取短数组的最佳方法?
Best way to read a short array from disk in C#?
我必须将 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;
}
}
shorts是两个字节,所以每次要读入两个字节。我还建议使用这样的 yield return
,这样您就不会试图一次将所有内容都拉入内存。虽然如果你需要所有的短裤在一起,那对你没有帮助..我猜取决于你用它做什么。
void Main()
{
short[] values = new short[] {
1, 999, 200, short.MinValue, short.MaxValue
};
WriteShortArray(values, @"C:\temp\shorts.txt");
foreach (var shortInfile in ReadShortArray(@"C:\temp\shorts.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
函数可以让你直接从OS磁盘缓存中读取类型为short
的数据.还有一个接受 Int16
的 Write()
重载。如果您正在调用需要传统 .NET 数组的函数,还有 ReadArray
和 WriteArray
函数。
Overview of using Memory-mapped files in .NET 在 MSDN
如果您想对普通文件 I/O 执行此操作,请使用 1 或 2 兆字节的块大小和 Buffer.BlockCopy
函数在 byte[]
和 short[]
,并使用接受 byte[]
的 FileStream
函数。忘记 BinaryWriter
或 BinaryReader
,忘记一次做 2 个字节。
也可以在 p/invoke 的帮助下将 I/O 直接放入 .NET 数组中,参见 my answer using ReadFile
and passing the FileStream
object's SafeFileHandle
property here 但是即使没有额外的副本,它仍然应该'跟上内存映射 ReadArray
和 WriteArray
调用。
我必须将 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;
}
}
shorts是两个字节,所以每次要读入两个字节。我还建议使用这样的 yield return
,这样您就不会试图一次将所有内容都拉入内存。虽然如果你需要所有的短裤在一起,那对你没有帮助..我猜取决于你用它做什么。
void Main()
{
short[] values = new short[] {
1, 999, 200, short.MinValue, short.MaxValue
};
WriteShortArray(values, @"C:\temp\shorts.txt");
foreach (var shortInfile in ReadShortArray(@"C:\temp\shorts.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
函数可以让你直接从OS磁盘缓存中读取类型为short
的数据.还有一个接受 Int16
的 Write()
重载。如果您正在调用需要传统 .NET 数组的函数,还有 ReadArray
和 WriteArray
函数。
Overview of using Memory-mapped files in .NET 在 MSDN
如果您想对普通文件 I/O 执行此操作,请使用 1 或 2 兆字节的块大小和 Buffer.BlockCopy
函数在 byte[]
和 short[]
,并使用接受 byte[]
的 FileStream
函数。忘记 BinaryWriter
或 BinaryReader
,忘记一次做 2 个字节。
也可以在 p/invoke 的帮助下将 I/O 直接放入 .NET 数组中,参见 my answer using ReadFile
and passing the FileStream
object's SafeFileHandle
property here 但是即使没有额外的副本,它仍然应该'跟上内存映射 ReadArray
和 WriteArray
调用。