C# 基于可用物理内存的阵列大小
我正在尝试做一个加密算法。 我可以读取一个文件并将其转换为字节而没有任何问题,并且正在将字节保存在byteArray中 问题是,我当前正在创建的数组大小如下所示:C# 基于可用物理内存的阵列大小,c#,arrays,C#,Arrays,我正在尝试做一个加密算法。 我可以读取一个文件并将其转换为字节而没有任何问题,并且正在将字节保存在byteArray中 问题是,我当前正在创建的数组大小如下所示: byte[] FileArray =new byte[10000000]; FileStream TheFileStream = new FileStream(FilePath.Text, FileMode.Open); BinaryReader TheFileBinary = new BinaryReader(TheFileStre
byte[] FileArray =new byte[10000000];
FileStream TheFileStream = new FileStream(FilePath.Text, FileMode.Open);
BinaryReader TheFileBinary = new BinaryReader(TheFileStream);
for (int i = 0; i < TheFileStream.Length; i++) {
FileArray = TheFileBinary.ReadBytes(10000000);
// I call a function here
if (TheFileStream.Position == TheFileStream.Length)
break;
}
ulong memoryKilobytes =
GetAvailableMemoryKilobytes();
// ...or GetTotalMemoryKilobytes();
int bufferSize = GetBufferSize(memoryKilobytes);
using (FileStream TheFileStream = new FileStream(FilePath.Text, FileMode.Open))
{
byte[] FileArray = new byte[bufferSize];
int readCount;
while ((readCount = TheFileBinary.Read(FileArray, 0, bufferSize)) > 0)
{
// Call a method here, passing FileArray as a parameter
}
}
byte[]FileArray=新字节[10000000];
FileStream TheFileStream=newfilestream(FilePath.Text,FileMode.Open);
BinaryReader TheFileBinary=新的BinaryReader(文件流);
for(int i=0;i
但是,我不希望数组大小是固定的,因为如果我将其设置为1000000(作为一个示例),其他内存大小较小的机器可能会遇到问题。
我需要找到每台机器内存大小的空闲大小,如何根据可用的未分配内存空间动态设置数组大小,以便将其放入byteArray
我注意到数组越大,读取速度就越快,所以我也不想让它太小。
我非常感谢您的帮助。如果您真的担心空间问题,请使用一个简单的列表,一次读取流中的数据块(比如1024),然后调用列表中的
AddRange
方法。完成后,在列表中调用ToArray
,现在就有了一个大小合适的字节数组
List<byte> byteArr = new List<byte>();
byte[] buffer = new byte[1024];
int bytesRead = 0;
using(FileStream TheFileStream = new FileStream(FilePath.Text, FileMode.Open))
{
while((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
byteArr.AddRange(buffer);
}
buffer = byteArr.ToArray();
// call your method here.
FileStream
跟踪文件中的字节数。只需使用Length
属性即可
FileStream TheFileStream = new FileStream(FilePath.Text, FileMode.Open);
BinaryReader TheFileBinary = new BinaryReader(TheFileStream);
byte[] FileArray = TheFileBinary.ReadBytes(TheFileStream.Length);
好的,重读这个问题,finnaly发现了问题的一部分,“我如何知道未分配的可用内存空间,以便将其放入byteArray中?”。无论如何,我建议您看看。您可以使用WMI检索的实例,并根据
FreePhysicalMemory
或TotalVisibleMemorySize
属性进行内存计算:
static ulong GetAvailableMemoryKilobytes()
{
const string memoryPropertyName = "FreePhysicalMemory";
using (ManagementObject operatingSystem = new ManagementObject("Win32_OperatingSystem=@"))
return (ulong) operatingSystem[memoryPropertyName];
}
static ulong GetTotalMemoryKilobytes()
{
const string memoryPropertyName = "TotalVisibleMemorySize";
using (ManagementObject operatingSystem = new ManagementObject("Win32_OperatingSystem=@"))
return (ulong) operatingSystem[memoryPropertyName];
}
然后将任一方法的结果传递给如下方法,以将读取缓冲区的大小缩放到本地计算机的内存:
static int GetBufferSize(ulong memoryKilobytes)
{
const int bufferStepSize = 256; // 256 kilobytes of buffer...
const int memoryStepSize = 128 * 1024;// ...for every 128 megabytes of memory...
const int minBufferSize = 512; // ...no less than 512 kilobytes...
const int maxBufferSize = 10 * 1024; // ...no more than 10 megabytes
int bufferSize = bufferStepSize * ((int) memoryKilobytes / memoryStepSize);
bufferSize = Math.Max(bufferSize, minBufferSize);
bufferSize = Math.Min(bufferSize, maxBufferSize);
return bufferSize;
}
显然,每128MB内存增加256KB的缓冲区大小似乎有点愚蠢,但这些数字只是示例,说明如果您真的想这样做,您可以如何扩展缓冲区大小。除非您同时读取很多文件,否则担心几百KB或几兆字节的缓冲区可能会带来更多麻烦。您最好只进行基准测试,看看哪种大小的缓冲区能够提供最佳性能(它可能不需要像您认为的那样大),然后使用它
现在,您可以像这样简单地更新代码:
byte[] FileArray =new byte[10000000];
FileStream TheFileStream = new FileStream(FilePath.Text, FileMode.Open);
BinaryReader TheFileBinary = new BinaryReader(TheFileStream);
for (int i = 0; i < TheFileStream.Length; i++) {
FileArray = TheFileBinary.ReadBytes(10000000);
// I call a function here
if (TheFileStream.Position == TheFileStream.Length)
break;
}
ulong memoryKilobytes =
GetAvailableMemoryKilobytes();
// ...or GetTotalMemoryKilobytes();
int bufferSize = GetBufferSize(memoryKilobytes);
using (FileStream TheFileStream = new FileStream(FilePath.Text, FileMode.Open))
{
byte[] FileArray = new byte[bufferSize];
int readCount;
while ((readCount = TheFileBinary.Read(FileArray, 0, bufferSize)) > 0)
{
// Call a method here, passing FileArray as a parameter
}
}
我正在尝试一种加密算法
那可能是个错误。安全加密很难实现。您要求的~10MB是一个相当小的数字。你为什么在这里担心内存问题?你遇到问题了吗?您是否预计将来在10MB非常多的设备上会出现特定问题?更好的方法(可以说)是制作自己的流。这可能是一个愚蠢的问题,但是如果你想要一个动态大小的数组,为什么不使用List
呢?他不想要一个动态大小的数组,他想要一个在运行时决定大小的数组。作者试图以最佳大小的块读取和处理文件,而这将一次性将整个文件读取到一个数组中。另外,FileStream.Length
属性拼写错误。您正在分块读取文件,但最终会得到存储在byteArray
和缓冲区中的整个文件的副本。作者担心内存的使用,一次只希望文件的一个块在内存中。