Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
快速文本阅读器c#_C#_C# 4.0 - Fatal编程技术网

快速文本阅读器c#

快速文本阅读器c#,c#,c#-4.0,C#,C# 4.0,我使用以下代码读取并组合一个字符串中的文本数: foreach (string path in filePaths) { StreamReader singfile = new StreamReader(path); string file_text = singfile.ReadToEnd(); combinetexts += file_tex

我使用以下代码读取并组合一个字符串中的文本数:

            foreach (string path in filePaths)
            {


                StreamReader singfile = new StreamReader(path);

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

                fs.Close();

            }
正如我所知,字符串combinetexts将复制文件路径数的n倍。是否可以使用字符串生成器执行此操作?我试过了,但没有。
提前感谢。

当然可以,使用

StringBuilder combinetexts = new StringBuilder();
...

combinetexts.Append(file_text);
combinetexts.Append("\n");;

使用StringBuilder操纵字符串更有效


致以最诚挚的问候

以下是您使用StringBuilder而不是字符串的示例:

var sb = new StringBuilder();

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

string result = sb.ToString();

(我还冒昧地缩短/优化了您的代码。无需手动打开StreamReader即可读取文件的完整内容。此外,
AppendLine
会在末尾自动添加一个
\n

以下是一个简单的LINQ方法:

string result = string.Join("\n", filePaths.Select(x => File.ReadAllText(x)));
或者使用C#4(它可以更好地处理类型推断wrt方法组转换):

若您使用的是.NET 3.5,则需要创建一个字符串数组,因为
string.Join
并没有那个么多重载:

string result = string.Join("\n", filePaths.Select(x => File.ReadAllText(x))
                                           .ToArray());
无可否认,这有一个缺点,即在执行串联之前读取所有文件,但它仍然比原始代码中的重复串联要好。它也可能比使用
StringBuilder
更有效-这取决于
string.Join
实现

请参阅my,了解原始代码效率低下的原因

编辑:请注意,这不包括结尾处的尾随
\n
。如果您真的想添加,您可以:)

尝试以下代码:

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());

是的,可以使用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();
}
最后,我将使用
使用(…)
而不是
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 result = string.Join("\n", filePaths.Select(File.ReadAllText));
string combinetexts = String.Join("\n", filePaths.Select(File.ReadAllText));
这将实现上述所有功能,它将:

  • 读入所有文件
  • Join将计算保存整个字符串所需的总大小
  • 然后它将合并所有文本,每个文本之间有一个
    \n

  • 使用字符串生成器执行相同的过程,以避免复制代码。非常感谢。我需要在文件路径中循环吗?@Jonemanni:不,LINQ会帮你做的。这就是替换问题中的代码所需的全部代码。请记住:StringBuilder不是一成不变的。