如何检测文件是否包含Unix换行符(\ n)或Windows换行符(\ r \ n)?

时间:2012-08-06 13:46:15

标签: c# windows file-io newline

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

该文件可以包含Unix或Windows换行符,因此我必须知道哪些文件可以在更新时将正确的换行符写回文件。

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

但是这个问题必须先解决,如果不是在C#中,那么在Win32 API中呢?

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

3 个答案:

答案 0 :(得分:3)

正如Per所说的那样,如果不打开文本文件并通过字节流式传输,就无法确定文本文件的内容。如果你使用http来下载文件,你可能会感到很幸运,你可以得到一个mime类型来说明文件的类型,但最常见的只是“octet-stream”。

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

1)选择要读取的字节样本大小,从文件中获取至少2或3条记录。

2)将每个字节遇到(i'massumign单字节字符集在此处)存储为直方图。您可以通过将计数存储在由字节值索引的arry中来执行此操作,也可以使用字典。

3)查看回车和换行值计数。如果您有换行计数且没有回车符,那么它是一个unix文件。如果carraige返回和换行计数,则它是一个Windows文件。

此方法还允许您对入站文件进行质量检查。你的直方图中的charcaters是不是aplha数字?然后有人通过了你一个二进制文件。期待所有大写?然后在upercase字符之外查找计数。您可以执行许多检查以防止处理非文本文件。

答案 1 :(得分:2)

不幸的是,如果它是Unix或DOS文件,我认为没有办法100%确定,因为大多数编辑在打开/保存时都没有更正带有'错误'结尾的文件。

我会将该文件作为流读取并搜索“\ r \ n”的出现次数并仅搜索“\ n”

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

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

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

答案 2 :(得分:2)

感谢大家的建议。我很惊讶没有找到容易重复使用的东西,所以我创建了一个我在这里包含的简单功能。请注意,它只是找到第一个换行符(\ n或\ r \ n)并将其作为匹配返回。足以满足我的需求,但也许并不健全。

    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;
        }
    }