「C Sharpの基礎 - CSVファイル」の版間の差分

ナビゲーションに移動 検索に移動
170行目: 170行目:
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
以下の例では、上記の例を非同期で行っている。<br>
以下の例では、大規模なCSVファイルでもメモリ効率を良くするため、ストリーミング処理を組み合わせて、上記の例を非同期で行っている。<br>
非同期処理は、I/O操作が頻繁に行われる場合、または、ユーザインターフェースの応答性を維持する必要がある場合に特に有効である。<br>
非同期処理は、I/O操作が頻繁に行われる場合、または、ユーザインターフェースの応答性を維持する必要がある場合に特に有効である。<br>
<br>
TextFieldParserクラスは同期的に動作するが、CSVファイルの各レコードの処理を別タスクで行うことにより、全体の処理を非同期に保つ。<br>
<br>
<br>
  <syntaxhighlight lang="c#">
  <syntaxhighlight lang="c#">
  // 非同期処理
  // 非同期処理
// ストリーミング処理
   
   
  using System;
  using System;
180行目: 183行目:
  using System.IO;
  using System.IO;
  using System.Threading.Tasks;
  using System.Threading.Tasks;
using Microsoft.VisualBasic.FileIO;
   
   
  class CSVParser
  class CSVParser
185行目: 189行目:
     static async Task Main()
     static async Task Main()
     {
     {
       string outputFile = "sample.txt";
       await ParseCSVAsync("sample.csv");
      await WriteCSVAsync(outputFile);
     }
     }
   
   
     static async Task WriteCSVAsync(string outputFile)
     static async Task ParseCSVAsync(string filePath)
     {
     {
       try
       try
       {
       {
           using (StreamWriter writer = new StreamWriter(outputFile, false, Encoding.GetEncoding("Shift_JIS")))
          // FileStreamクラスを使用して、ファイルを非同期でストリーミング読み込み
           using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 4096, useAsync: true))
          using (var streamReader = new StreamReader(fileStream, Encoding.GetEncoding("Shift_JIS")))
          using (var parser = new TextFieldParser(streamReader))
           {
           {
             // ヘッダ行を書き込む
             parser.TextFieldType = FieldType.Delimited;
            await writer.WriteLineAsync("列1,列2,列3");
            parser.Delimiters = new[] { "," };
            parser.CommentTokens = new[] { "#" };
            while (!parser.EndOfData)
            {
                // ファイルを非同期で1行ずつ読み込む
                string line = await streamReader.ReadLineAsync();
                if (line == null) break;
                // 行の解析と処理を別タスクで実行
                await Task.Run(() =>
                {
                  try
                  {
                      string[] fields = parser.ReadFields();
                      if (fields != null)
                      {
                        foreach (string field in fields)
                        {
                            string processedField = field.Replace("\r\n", "n").Replace(" ", "_");
                            Console.Write(processedField + "\t");
                        }
   
   
            // レコード行を書き込む
                        Console.WriteLine();
            await writer.WriteLineAsync("値1,値2,値3");
                      }
            await writer.WriteLineAsync("値4,\"値5,カンマを含む\",値6");
                  }
            await writer.WriteLineAsync("値7,値8,\"値9\n改行を含む\"");
                  catch (Exception ex)
                  {
                      Console.WriteLine($"行の処理中にエラーが発生: {ex.Message}");
                  }
                });
            }
           }
           }
       }
       }
       catch (Exception ex)
       catch (Exception ex)
       {
       {
           Console.WriteLine("書き込みエラー: " + ex.Message);
           Console.WriteLine($"ファイルの処理中にエラーが発生: {ex.Message}");
       }
       }
     }
     }

案内メニュー