1

次のコードを使用して、txt ファイルに書き込まれた 16 進文字列をバイト ファイルに変換しています。問題は、大きな txt ファイルを処理できず、「メモリ不足の例外」が発生することです。「チャンク」で行う必要があることは知っていますが、正しくできません。

助けてください!コード:

protected void Button1_Click(object sender, EventArgs e)
{
    {
        string tempFileName = (Server.MapPath("~\\Tempfolder\\" + FileUpload2.FileName));

        using (FileStream fs = new FileStream(tempFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        using (StreamReader sr = new StreamReader(fs))
        {

            string s = (sr.ReadToEnd());
            if (s.Length % 2 == 1) { lblispis.Text = "String must have an even length"; }
            else
            {
               string hexString = s;
                File.WriteAllBytes(tempFileName + ".bin", StringToByteArray(hexString));
                lblispis.Text = "Done.";
            }
        }
    }                            
 }
public static byte[] StringToByteArray(String hex)
{
    int NumberChars = hex.Length;
    byte[] bytes = new byte[NumberChars / 2];
    for (int i = 0; i < NumberChars; i += 2)
        bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
    return bytes;
}
4

2 に答える 2

2

ファイル形式で許可されている場合は、ReadToEnd呼び出しを置き換えてループでラップすることができます。ReadLine

そうでない場合は、ファイルの最後に到達するまで偶数文字 ( ) を読み取るオプションが常にありRead(char[], int, int)ます。もちろん、そのようにして、すでにかなりの作業を行った後、文字の数が奇数であることを非常に遅く検出します。

于 2012-06-03T19:15:52.737 に答える
1

@Wormboの回答に追加するには、16進文字列にはバイト配列の2倍の文字しか含まれていないことに注意してください。.NET では、オブジェクト サイズの制限は 2GB (2GB は実際には 32 ビット マシンでのプロセス サイズの制限です) ですが、ヒープの断片化が原因で、最大 800MB の連続ブロックを割り当てるのに問題が発生する可能性があります。

つまり、変換後すぐにディスクに直接書き込む必要があります。

using (StreamReader reader = new StreamReader(hex))
using (BinaryWriter writer = new BinaryWriter(File.Open(bin, FileMode.Create)))
{
     string line;
     while ((line = reader.ReadLine()) != null)
         writer.Write(StringToByteArray(line));
}

[編集]

私はそれを修正しました。割り当ての周りに括弧を追加する必要がありました(while上記のステートメントを確認してください)。

これは次のようなものの省略形にすぎないことに注意してください。

     string line = reader.ReadLine();
     while (line != null) 
     {
          writer.Write(...);
          line = reader.ReadLine();
     }
于 2012-06-03T19:35:10.133 に答える