我正在通过FileStream改变文件(它是一个非常大的文件,我只需要改变标题而不重写整个文件。
该文件可以包含Unix或Windows换行符,因此我必须知道哪些文件可以在更新时将正确的换行符写回文件。
我可以编写一个简单的函数来使用FileStream来读取块中的文件并检查换行符。
但是这个问题必须先解决,如果不是在C#中,那么在Win32 API中呢?
检测文件换行方式的最有效方法是什么?
答案 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;
}
}