C# 基于可用物理内存的阵列大小

C# 基于可用物理内存的阵列大小,c#,arrays,C#,Arrays,我正在尝试做一个加密算法。 我可以读取一个文件并将其转换为字节而没有任何问题,并且正在将字节保存在byteArray中 问题是,我当前正在创建的数组大小如下所示: byte[] FileArray =new byte[10000000]; FileStream TheFileStream = new FileStream(FilePath.Text, FileMode.Open); BinaryReader TheFileBinary = new BinaryReader(TheFileStre

我正在尝试做一个加密算法。 我可以读取一个文件并将其转换为字节而没有任何问题,并且正在将字节保存在byteArray中

问题是,我当前正在创建的数组大小如下所示:

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
缓冲区中的整个文件的副本。作者担心内存的使用,一次只希望文件的一个块在内存中。