10

我正在通过 FileStream 更改文件(这是一个非常大的文件,我只需要更改标题而不重写整个文件。

该文件可以有 Unix 或 Windows 换行符,对我来说知道哪个很重要,这样我可以在更新文件时将正确的换行符写回文件中。

我可以编写一个简单的函数来使用 FileStream 以块的形式读取文件并检查换行符。

但是这个问题之前肯定已经解决了,如果不是在 C# 中,那么在 Win32 API 中呢?

检测文件换行样式的最有效方法是什么?

4

3 回答 3

4

Thanks all for your suggestions. I was surprised not to find something easily reusable, so I created a simple function that I include here. Note that it just finds the first newline character (\n or \r\n) and returns that as the match. Enough for my needs, but perhaps not robust.

    public bool TryDetectNewLine(string path, out string newLine)
    {
        using (var fileStream = File.OpenRead(path))
        {
            char prevChar = '\0';

            // Read the first 4000 characters to try and find a newline
            for (int i = 0; i < 4000; i++)
            {
                int b;
                if ((b = fileStream.ReadByte()) == -1) break;

                char curChar = (char)b;

                if (curChar == '\n')
                {
                    newLine = prevChar == '\r' ? "\r\n" : "\n";
                    return true;
                }

                prevChar = curChar;
            }

            // Returning false means could not determine linefeed convention
            newLine = Environment.NewLine;
            return false;
        }
    }
于 2012-08-06T16:46:28.970 回答
3

正如 Per 所说,如果不打开文本文件并通过字节流式传输,实际上没有办法确定文本文件的内容。如果您使用 http 下载文件,您可能会很幸运,您可以获得一个指示文件类型的 mime 类型,但通常它只是“八位字节流”。

虽然您可以强制使用它,并阅读直到找到换行符(“\n”)然后备份一个字符并查看是否有回车符(“\r”),但我会采取更统计的方法,因为你有以任何方式读取数据。

1)选择一个字节的样本大小来读取,这应该可以从文件中获得至少 2 或 3 条记录。

2)将每个字节遇到(我在这里设置单字节字符)存储为直方图。您可以通过将计数存储在由字节值索引的数组中来做到这一点,或者您可以使用字典。

3) Take a look at the carriage return and line feed values counts. If you have a line feed count and no carriage returns, then it is a unix file. If carraige return and line feed counts then it is a windows file.

What this approach also would allow you to do is to a quality check on the inbound file. Do you have charcaters in you histogram that are not aplha numeric ? Then someone has passed you a binary file. Expecting all upper case ? Then look for counts outside the upercase characters. There are a number of checks you could do to keep from processing a non text file.

于 2012-08-06T14:41:40.640 回答
2

不幸的是,我认为没有办法 100% 确定它是 Unix 还是 DOS 文件,因为大多数编辑器在打开/保存时不会更正具有“错误”结尾的文件。

我会将文件作为流读取并搜索“\r\n”的出现,并且只搜索“\n”

对搜索结果使用简单的统计分析(即哪个具有最高的命中数)可能会给您正确的答案。如果文件很大,那么读取文件的前 X% 就足够了。

一个更简单的解决方案当然是只搜索“\r\n”,如果找到,就假设它是一个 DOS 文件。如果文件是机器生成的,这应该可以 100% 工作。

至于 .NET Framework/WinAPI 中的任何现有代码,我还没有看到任何执行此操作的代码。

于 2012-08-06T14:17:13.273 回答