-1

次のコードを使用して、1つの文字列に多数のテキストを読み取って結合しています。

            foreach (string path in filePaths)
            {


                StreamReader singfile = new StreamReader(path);

                string  file_text = singfile.ReadToEnd();
                combinetexts += file_text + "\n";

                fs.Close();

            }

私が知っているように、文字列combinetextsはファイルパスの数のn倍をコピーします。文字列ビルダーを使用してその手順を実行することは可能ですか?試しましたが、しません。前もって感謝します。

4

6 に答える 6

8

これを行うための短いLINQの方法は次のとおりです。

string result = string.Join("\n", filePaths.Select(x => File.ReadAllText(x)));

または、C#4(メソッドグループ変換による型推論の処理が優れている)の場合:

string result = string.Join("\n", filePaths.Select(File.ReadAllText));

.NET 3.5を使用している場合は、文字列の配列を作成する必要があります。これは、string.Joinオーバーロードがそれほど多くなかったためです。

string result = string.Join("\n", filePaths.Select(x => File.ReadAllText(x))
                                           .ToArray());

これには、確かに、連結を実行する前にすべてのファイルを読み取るという欠点がありますが、元のコードで繰り返される連結よりも優れています。また、使用するよりも効率的かもしれませんStringBuilder-それは実装に依存しstring.Joinます。

元のコードが本当に非効率的である理由については、私の記事を参照してください。StringBuilder

編集:これには最後の末尾が含まれていない\nことに注意してください。本当にそれを追加したい場合は、次のことができます:)

于 2012-05-09T09:58:24.673 に答える
1

もちろん可能です、使用

StringBuilder combinetexts = new StringBuilder();
...

combinetexts.Append(file_text);
combinetexts.Append("\n");;
于 2012-05-09T09:56:25.063 に答える
1

文字列の代わりにStringBuilderを使用した例を次に示します。

var sb = new StringBuilder();

foreach (string path in filePaths) 
    sb.AppendLine(File.ReadAllText(path)); 

string result = sb.ToString();

(コードを少し短縮/最適化するためにも自由を取りました。File.ReadAllTextは、StreamReaderを手動で開かなくても、ファイルの内容全体を読み取ります。さらに、最後にAppendLine自動的にを追加します\n。)

于 2012-05-09T09:58:13.523 に答える
0

StringBuilderを使用して文字列を操作する方が効率的です。

http://www.codeproject.com/Articles/14936/StringBuilder-vs-String-Fast-String-Operations-wit

よろしくお願いします

于 2012-05-09T09:57:19.180 に答える
0

以下のコードを試してください。

StringBuilder strBuilder= new StringBuilder();
foreach (string path in filePaths)
{
     StreamReader singfile = new StreamReader(path);
     string  file_text = singfile.ReadToEnd();
     strBuilder.AppendLine(file_text);
     fs.Close();
}
Console.WriteLine(strBuilder.ToString());
于 2012-05-09T09:58:37.327 に答える
0

はい、StringBuilderを使用することは可能です。このコードを「最適化」するには、さまざまな方法があります。

TL; DR:これを行うための最良の方法については、この投稿の最後の部分にスキップしてください。

コードのステージ1の変更は次のとおりです。

StringBuilder combinetexts = new StringBuilder();
foreach (string path in filePaths)
{
    StreamReader fs = new StreamReader(path);

    string  file_text = fs.ReadToEnd();
    combinetexts.Append(file_text).Append("\n");

    fs.Close();
}

次に、ビルドする前に、StringBuilder実際に必要なスペースの量を計算できます。これにより、文字列をさらにコピーする可能性が低くなります。

long totalSize = 0;
foreach (string path in filePaths)
    totalSize += new FileInfo(path).Length + 1; // +1 = \n

StringBuilder sb = new StringBuilder(Convert.ToInt32(totalSize));
foreach (string path in filePaths)
{
    StreamReader fs = new StreamReader(path);

    string  file_text = fs.ReadToEnd();
    combinetexts.Append(file_text).Append("\n");

    fs.Close();
}

最後にusing (...)、呼び出しの代わりに使用しfs.Close();ます:

long totalSize = 0;
foreach (string path in filePaths)
    totalSize += new FileInfo(path).Length + 1; // +1 = \n

StringBuilder sb = new StringBuilder(Convert.ToInt32(totalSize));
foreach (string path in filePaths)
{
    using (StreamReader fs = new StreamReader(path))
    {
        string  file_text = fs.ReadToEnd();
        combinetexts.Append(file_text).Append("\n");
    }
}

次に、LINQをもう少し使用してFile.ReadAllText、明示的なの代わりに使用に切り替えてからStreamReader、コード行を少し組み合わせます。

long totalSize = filePaths.Sum(path => new FileInfo(path).Length + 1);

StringBuilder sb = new StringBuilder(Convert.ToInt32(totalSize));
foreach (string path in filePaths)
{
    combinetexts.Append(File.ReadAllText(path)).Append("\n");
}

ただし、結局のところ、これを行うにはさらに良い方法があります。

string combinetexts = String.Join("\n", filePaths.Select(path => File.ReadAllText(path)));

またはC#4.0では、メソッドグループの変換を処理する正しい方法をより適切に推測できます。

string combinetexts = String.Join("\n", filePaths.Select(File.ReadAllText));

これにより、上記のすべてが実行されます。

  1. すべてのファイルを読み込む
  2. String.Joinは、文字列全体を保持するために必要な合計サイズを計算します
  3. 次に、すべてのテキストを結合します\n
于 2012-05-09T10:03:34.720 に答える