4

我想将两个文本文件附加在一起。

我有一个文件,最后有一个回车换行符。观察文件 A,它是 28 个字节。

这是文件中的一行\n

然后我有另一个没有新行的文件。观察 26 字节的文件 B。

这是文件中的一行

我想将相同的文件附加到自身(文件 A 到 A,文件 B 到 B)并比较字节数。

但是,StreamReader.ReadLine()在文件 A 上使用时,我得到一个返回值,但 MSDN 说:

行定义为字符序列后跟换行符 ("\n")、回车符 ("\r") 或回车符后紧跟换行符 ("\r\n")。返回的字符串不包含终止的回车符或换行符。如果到达输入流的末尾,则返回值为 null。

但是,文件中没有crlf。

如何安全地附加这些文件而不在末尾添加额外的换行符?例如,StreamWriter.WriteLine()当我不想这样做时,会在文件 A 上放置一个额外的换行符。什么是理想的方法?

4

4 回答 4

3

只有在流结束时null调用才会得到。否则,您将获取所有数据,直到流结束结束。ReadLine CRLF

如果您尝试进行逐字节复制(和比较),StreamReader最好StreamWriter使用Stream普通ReadWrite函数而不是ReadLineand WriteLine

您也可以使用读取文件的全部内容,ReadToEnd然后通过调用Write(not WriteLine) 将其写入,但如果文件很大,这不切实际。

string data;

using(StreamReader reader = new StreamReader(path))
{
    data = reader.ReadToEnd();
}

using(StreamWriter writer = new StreamWriter(path, true))
{
    writer.Write(data);
}
于 2010-08-10T02:19:08.443 回答
2

您可以使用 StreamWriter.Write 而不是 WriteLine 来避免额外的 crlf。

至于 ReadLine 文档,我相信这个问题是一个措辞不当的解释。您当然不希望仅仅因为没有正式的行结束标志而丢弃文件的最后一个字节。

于 2010-08-10T02:17:44.920 回答
2

StreamReader 和 StreamWriter(派生自 TextReader 和 TextWriter)不适用于需要精确形式的二进制数据的情况。它们是由字节组成的文件的高级抽象,而不是文本或行。事实上,您不仅可以使用不同数量的换行符,而且根据环境,您可能会写出预期的 CR/LF 之外的行终止符。

相反,您应该只从一个流复制到另一个流。这实际上很容易。

var bytes = File.ReadAllBytes(pathIn);
var stream = File.Open(pathOut, FileMode.Append);
stream.Write(bytes, 0, bytes.Length);
stream.Close();

如果文件的大小可能很大,您应该同时打开输入和输出文件,并使用固定大小的缓冲区一次复制一个块。

using (var streamIn = File.Open(pathIn, FileMode.Read))
using (var streamOut = File.Open(pathOut, FileMode.Append)) {

    var bytes = new byte[BLOCK_SIZE];

    int count;
    while ((count=streamIn.Read(bytes, 0, bytes.Length)) > 0) {
        streamOut.Write(bytes, 0, count);
    }

}

另外值得注意的是,上面的代码可以被.NET 4 中的新Stream.CopyTo替换。

于 2010-08-10T02:23:39.920 回答
0

好吧,这实际上取决于您实现的原因(为什么要逐行阅读并逐行写回?)您可以使用StreamWriter.Write(string)并输出您存储的所有文本,这些WriteLine()方法之所以这样命名,是因为它们附加了一个新队。

TextWriter.WriteLine 方法 (String)
将后跟行终止符的字符串写入文本流。

于 2010-08-10T02:13:01.077 回答