1

我需要能够获取具有未知编码(例如,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!请记住,我对输入文件编码没有先验知识。

4

2 回答 2

8

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

这是要解决的根本问题。

如果文件可以使用任何编码,则没有“逐行”读取的概念,因为您不可能知道行尾是什么。

我建议你先解决这部分,剩下的就很容易了。现在,在不了解上下文的情况下,很难说这是否意味着您应该向用户询问编码,或者启发式地检测它,或者其他方式 - 但在您完全理解之前我不会开始尝试使用数据。

于 2014-01-07T20:20:53.963 回答
0

正如经常发生的那样,当您寻求帮助时,答案就会浮出水面。注释掉的代码变成:

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;
}
于 2014-01-07T20:14:31.107 回答