-->

在C#中,我如何可以复制任意编码文件,读一行行,无需添加或删除换行符(In C#, How can

2019-10-19 05:08发布

我需要能够随身携带未知编码的文本文件(例如,UTF-8,UTF-16,......)和逐行复制,提出具体的修改,我去。 在这个例子中,我改变了编码,但也有其他用途这种处理。

我无法弄清楚是如何确定的最后一行有一行! 某些程序在乎这些记录的文件之间的差异:

Rec1<newline>
Rec2<newline>

并与这些文件:

Rec1<newline>
Rec2

我怎样才能看出其中的差别在我的代码,这样我可以采取适当的行动?

using (StreamReader reader = new StreamReader(sourcePath))
using (StreamWriter writer = new StreamWriter(destinationPath, false, outputEncoding))
{
    bool isFirstLine = true;

    while (!reader.EndOfStream)
    {
        string line = reader.ReadLine();

        if (isFirstLine)
        {
            writer.Write(line);
            isFirstLine = false;
        }
        else
        {
            writer.Write("\r\n" + line);
        }
    }


    //if (LastLineHasNewline)
    //{
    //  writer.Write("\n");
    //}

    writer.Flush();
}

注释掉的代码是什么,我希望能够做的,但我无法弄清楚如何设置条件lastInputLineHadNewline! 请记住,我没有输入文件编码的先验知识。

Answer 1:

请记住,我没有输入文件编码的先验知识。

这是要解决的根本问题。

如果该文件可以使用任何编码,那么有没有阅读“逐行”的概念,因为你不可能知道线路的结局是什么。

我建议你先解决这部分,剩下的将是容易的。 现在不知道情况下,很难说这是否意味着你应该问的编码用户,或启发式检测,或别的东西-但我不会开始尝试使用数据,然后才能完全理解



Answer 2:

正如经常发生的,你去寻求帮助的时刻,答案来到表面。 注释掉的代码变为:

if (LastLineHasNewline(reader))
{
    writer.Write("\n");
}

和函数如下:

private static bool LastLineHasNewline(StreamReader reader)
{
    byte[] newlineBytes = reader.CurrentEncoding.GetBytes("\n");
    int newlineByteCount = newlineBytes.Length;

    reader.BaseStream.Seek(-newlineByteCount, SeekOrigin.End);

    byte[] inputBytes = new byte[newlineByteCount];
    reader.BaseStream.Read(inputBytes, 0, newlineByteCount);
    for (int i = 0; i < newlineByteCount; i++)
    {
        if (newlineBytes[i] != inputBytes[i])
            return false;
    }
    return true;
}


文章来源: In C#, How can I copy a file with arbitrary encoding, reading line by line, without adding or deleting a newline