4

私は C# のファイルに少し慣れておらず、問題を抱えています。ファイルから読み取って別のファイルにコピーすると、テキストの最後のチャンクが書き込まれません。以下は私のコードです:

StringBuilder sb = new StringBuilder(8192);
string fileName = "C:...rest of path...inputFile.txt";
string outputFile = "C:...rest of path...outputFile.txt";

using (StreamReader reader = File.OpenText(fileName))
{
   char[] buffer = new char[8192];
   while ((reader.ReadBlock(buffer, 0, buffer.Length)) != 0)
   {
      foreach (char c in buffer)
      {
         //do some function on char c... 
         sb.Append(c);
      }

      using (StreamWriter writer = File.CreateText(outputFile))
      {
         writer.Write(sb.ToString());
      }
   }
}

私の目的は、バッファリングされた方法でテキストファイルを読み書きすることでした。Javaで次の方法で達成するもの:

public void encrypt(File inputFile, File outputFile) throws IOException
{
   BufferedReader infromfile = null;
   BufferedWriter outtofile = null;

   try
   {
      String key = getKeyfromFile(keyFile);
      if (key != null)
      {
         infromfile = new BufferedReader(new FileReader(inputFile));
         outtofile = new BufferedWriter(new FileWriter(outputFile));
         char[] buffer = new char[8192];
         while ((infromfile.read(buffer, 0, buffer.length)) != -1)
         {
            String temptext = String.valueOf(buffer);
            //some changes to temptext are done
            outtofile.write(temptext);
         }
      }
   }
   catch (FileNotFoundException exc)
   {
   } // and all other possible exceptions
}

問題の原因を特定するのを手伝ってもらえますか?

テキスト ファイルでバッファー I/O を実現するためのより良い方法があると思われる場合は、ご提案をいただければ幸いです。

4

5 に答える 5

1

これを試して:

        string fileName = @"";
        string outputfile = @"";

        StreamReader reader = File.OpenText(fileName);
        string texto = reader.ReadToEnd();

        StreamWriter writer = new StreamWriter(outputfile);
        writer.Write(texto);

        writer.Flush();
        writer.Close();
于 2012-05-17T14:23:46.803 に答える
1

いくつかの「落とし穴」があります。

  1. c変更することはできません (これは foreach 反復変数です)。書き込む前に処理するには、コピーする必要があります。
  2. バッファのサイズを追跡する必要がありReadBlock、出力を汚す文字で埋めます

コードを次のように変更すると、うまくいくように見えます。

//extracted from your code
foreach (char c in buffer)
{
    if (c == (char)0) break; //GOTCHA #2: maybe you don't want NULL (ascii 0) characters in your output

    char d = c; //GOTCHA #1: you can't change 'c'

    // d = SomeProcessingHere();

    sb.Append(d);
}
于 2012-05-17T14:18:12.570 に答える
0

私が何かを見逃していない限り、あなたの問題は、ブロック読み取りの反復ごとに出力ファイルの既存の内容を上書きしていることであるように見えます。

あなたが呼ぶ:

  using (StreamWriter writer = File.CreateText(outputFile))
  {
     writer.Write(sb.ToString());
  }

ReadBlockの反復ごとに。ファイルの出力は、読み取られたデータの最後のチャンクのみになります。

File.CreateTextのMSDNドキュメントから:

パスで指定されたファイルが存在しない場合は作成されます。ファイルが存在する場合、その内容は上書きされます。

于 2012-05-17T14:39:24.520 に答える
0

これはうまくいきますか?

       using (StreamReader reader = File.OpenText(fileName))
       {
            char[] buffer = new char[8192];
            bool eof = false;

            while (!eof)
            {
                int numBytes = (reader.ReadBlock(buffer, 0, buffer.Length));
                if (numBytes>0)
                {
                    using (StreamWriter writer = File.CreateText(outputFile))
                    {
                        writer.Write(buffer, 0, numBytes);
                    }
                } else {
                    eof = true;
                }

            }
        }

ただし、文字エンコーディングにはまだ注意が必要です。

于 2012-05-17T14:23:34.513 に答える
0

キャレインの返品を気にしない場合は、次を使用できますFile.ReadAllText

このメソッドは、ファイルを開き、ファイルの各行を読み取り、各行を文字列の要素として追加します。次に、ファイルを閉じます。行は、一連の文字の後にキャリッジ リターン ('\r')、ライン フィード ('\n')、またはキャリッジ リターンの直後にライン フィードが続くものとして定義されます。結果の文字列には、終了のキャリッジ リターンやライン フィードが含まれません。

StringBuilder sb = new StringBuilder(8192);
string fileName = "C:...rest of path...inputFile.txt";
string outputFile = "C:...rest of path...outputFile.txt";

// Open the file to read from.
string readText = File.ReadAllText(fileName );
foreach (char c in readText)
{
   // do something to c
   sb.Append(new_c);
}

// This text is added only once to the file, overwrite it if it exists
File.WriteAllText(outputFile, sb.ToString());        
于 2012-05-17T14:20:35.373 に答える