我使用以下代码在一个字符串中读取和组合文本数量:
foreach (string path in filePaths)
{
StreamReader singfile = new StreamReader(path);
string file_text = singfile.ReadToEnd();
combinetexts += file_text + "\n";
fs.Close();
}
据我所知,字符串combinetexts将复制n次文件路径的数量。是否可以使用字符串生成器来执行此操作?我尝试过,但事实并非如此。 提前谢谢。
答案 0 :(得分: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
实现。
请参阅我的article on StringBuilder
了解原始代码为何效率低下的原因。
编辑:请注意,不在结尾处包含尾随\n
。如果确实想要添加它,您可以:)
答案 1 :(得分:1)
当然可以,使用
StringBuilder combinetexts = new StringBuilder();
...
combinetexts.Append(file_text);
combinetexts.Append("\n");;
答案 2 :(得分: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
。)
答案 3 :(得分:0)
使用StringBuilder来操作字符串会更有效。
http://www.codeproject.com/Articles/14936/StringBuilder-vs-String-Fast-String-Operations-wit
祝你好运
答案 4 :(得分: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());
答案 5 :(得分: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));
这将完成上述所有,它将:
\n
醇>