我正在做的项目列表的一部分是一个小文本编辑器。
At one point, you can load all the sub directories and files in a given directory.程序将每个作为节点添加到TreeView中。
我想要的功能是只添加普通文本阅读器可读的文件。
此代码目前将其添加到树中:
TreeNode navNode = new TreeNode();
navNode.Text = file.Name;
navNode.Tag = file.FullName;
directoryNode.Nodes.Add(navNode);
我知道我可以使用类似的东西轻松创建一个if语句:
if(file.extension.equals(".txt"))
但我必须扩展该语句以包含它可能的每一个扩展名。
有更简单的方法吗?我认为它可能与mime类型或文件编码有关。
答案 0 :(得分:4)
没有通用的方法来计算存储在文件中的信息类型。
即使您事先知道如果您不知道用于创建文件的编码是某种文本,您也可能无法正确加载它。
请注意,HTTP会按内容类型标题提供有关文件类型的一些提示,但文件系统上没有此类信息。
答案 1 :(得分:1)
有一些方法可以用来“最好地猜测”文件是否是文本文件。当然,你支持的编码越多,这就越难,特别是如果计划支持CJK(中文,日语,韩文)脚本。我们暂时从Encoding.Ascii
和Encoding.UTF-8
开始。
幸运的是,大多数非文本文件(可执行文件,图像,等)在其中包含大量不可解析的字符前几千字节。
你可以做的是拿一个文件并扫描前1-4KB(由你决定)并查看是否有任何“不可打印”的字符出现。此操作不应花费太多时间,至少可以确定文件的内容。
public static async Task<bool> IsValidTextFileAsync(string path,
int scanLength = 4096)
{
using(var stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read))
using(var reader = new StreamReader(stream, Encoding.UTF8))
{
var bufferLength = (int)Math.Min(scanLength, stream.Length);
var buffer = new char[bufferLength];
var bytesRead = await reader.ReadBlockAsync(buffer, 0, bufferLength);
reader.Close();
if(bytesRead != bufferLength)
throw new IOException("There was an error reading from the file.");
for(int i = 0; i < bytesRead; i++)
{
var c = buffer[i];
if(char.IsControl(c))
return false;
}
return true;
}
}
答案 2 :(得分:0)
一种hacky方法是查看文件是否包含任何不是白色空间形式的下控制字符(0-31)(回车,制表符,垂直制表符,换行符,以及安全无效和文本结束)。如果是,那么它可能是二进制的。如果没有,可能不是。我没有做任何测试或任何事情,看看将这个规则应用于非ASCII编码时会发生什么,所以你必须自己进一步调查:)
答案 3 :(得分:0)
我的方法基于@Rubenisme的评论和@Erik的答案。
public static bool IsValidTextFile(string path)
{
using (var stream = System.IO.File.Open(path, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read))
using (var reader = new System.IO.StreamReader(stream, System.Text.Encoding.UTF8))
{
var bytesRead = reader.ReadToEnd();
reader.Close();
return bytesRead.All(c => // Are all the characters either a:
c == (char)10 // New line
|| c == (char)13 // Carriage Return
|| c == (char)11 // Tab
|| !char.IsControl(c) // Non-control (regular) character
);
}
}