2012-03-12 7 views
0

暗号化アルゴリズムを作成しようとしています。 ファイルを読み込んで問題なくバイトに変換し、バイトを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; 
} 

を、私はそれが1000000(一例として)にする場合ので、私は、配列のサイズが固定されないようにします、メモリサイズの小さな他のマシンで問題が発生する可能性があります。 各マシンのメモリサイズのアイドルサイズを見つける必要があります。割り当てられていない空きメモリ容量に基づいて配列サイズを動的に設定し、byteArrayに配置できる場所はどのようにすればよいですか?

私は、Arraysizeが大きいほど気付きましたが、読み込みが速くなると気づきました。私はそれを小さすぎるようにしたくありません。 私は本当に助けに感謝します。

+9

'それはおそらく間違いだalgorithm'暗号化をしようとしています。安全な暗号は_hard_です。 – SLaks

+2

あなたが求めている〜10MBはかなり少量です。なぜあなたはここの記憶問題を心配していますか?あなたは問題に遭遇しましたか?将来、10MBが多いデバイスでは、特定の問題が予想されますか? – dlev

+2

(間違いなく)_better_アプローチはあなた自身のストリームを作ることでしょう。 –

答えて

0

スペースが本当に心配なのであれば、シンプルなリストを使用して、一度にストリームのチャンク(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. 

編集:大きなファイルの場合は、チャンクで読み込むことをお勧めします。もちろん、バッファサイズで再生することもできますが、通常は1024で始まります。ファイル全体の読み込みを行うと、最終的にメモリが倍増します。ストリームのサイズ(自分のバッファの上にある)である内部読み込みバッファも処理する必要があります。読み込みをチャンクに分割するのは、FileStream.Length * 2ではなく、FileStream.Length + <buffer size>のメモリしか必要としません。覚えておいてください。

byte[] buffer = null; 
using(FileStream TheFileStream = new FileStream(FilePath.Text, FileMode.Open)) 
{ 
    buffer = new byte[TheFileStream.Length]; 
    int offset = 0; 
    while((bytesRead = stream.Read(buffer, offset, 1024)) > 0) 
     offset += bytesRead; 
    // Or just TheFileStream.Read(buffer, 0, buffer.Length) if it's small enough. 
} 
+0

あなたは塊でファイルを読んでいますが、最終的に 'byteArray'と' buffer'の両方に保存されたファイル全体のコピーで終わります。著者はメモリの使用を心配しており、一度に1つのファイルのチャンクだけをメモリに格納することを望んでいます。 – BACON

0

FileStreamはファイル内のバイト数を記録しています。ちょうどLengthプロパティを使用してください。

FileStream TheFileStream = new FileStream(FilePath.Text, FileMode.Open); 
BinaryReader TheFileBinary = new BinaryReader(TheFileStream); 
byte[] FileArray = TheFileBinary.ReadBytes(TheFileStream.Length); 

オーケー質問を再読し、finnaly質問、「私は、ByteArrayにそれを置くことができますので、どのように私は自由な未割り当てメモリ空間を知ることができる」だったそれの一部を発見しました。とにかく私はあなたがthis question along with its highest rated commentを見てみることをお勧めします。

+0

著者は最適なサイズのチャンクでファイルを読み込んで処理しようとしていますが、ファイル全体を一度にすべて読み込みます。また、 'FileStream.Length'プロパティのスペルが間違っています。 – BACON

0

あなたはWin32_OperatingSystem classのインスタンスを取得し、FreePhysicalMemoryまたはTotalVisibleMemorySizeの特性を離れてあなたのメモリの計算をベースにWMIを使用することができます。

static ulong GetAvailableMemoryKilobytes() 
{ 
    const string memoryPropertyName = "FreePhysicalMemory"; 

    using (ManagementObject operatingSystem = new ManagementObject("[email protected]")) 
     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; 
} 

明らかに、RAMのすべての128メガバイトのために256キロバイトしてバッファサイズを大きくすると、少し愚かなようだが、これらの数は単なる例であり、もしあなたが本当にそれをやりたければ、あなたのバッファサイズをどのように拡大するかもしれません。たくさんのファイルを一度に読んでいるのでなければ、数百キロバイトまたは数メガバイトのバッファーを心配するのは、それが価値あるものよりも難しいかもしれません。ベンチマークを行うだけで、どのサイズのバッファが最高のパフォーマンスを発揮するかを確認することができます。

今、あなたは、単にこのようにコードを更新することができます。

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 
    } 
}