如何在C#中使用FileStream打开文件时测试文件是否为“文本类型”文件?我希望我的程序可以打开任何文本基础文件,例如.txt、.html等。
但不要打开诸如.doc、.pdf或.exe等文件。
如何在C#中使用FileStream打开文件时测试文件是否为“文本类型”文件?我希望我的程序可以打开任何文本基础文件,例如.txt、.html等。
但不要打开诸如.doc、.pdf或.exe等文件。
一般情况下:无法判断。
如果你使用8位编码打开以UTF-16格式存储的文本文件,它可能看起来像是二进制文件。同样地,某人可以将文本文件保存为.doc
(它是一个文档)。
虽然你可以打开文件并查看其中一些内容,但这些启发式方法有时会失败(例如,记事本尝试这样做,通过精选几个字符,记事本会猜错并显示完全不同的内容)。
如果你有具体的场景,而不是能够打开和处理任何东西,那么应该能够做得更好。
正如其他人指出的那样,没有绝对确定的方法。但是为了确定一个文件是否为二进制文件(相对于确定它是否为文本文件来说要容易一些),有些实现会检查连续的NUL字符。Git似乎只检查前8000个字符中是否存在NUL字符,如果找到一个则将该文件视为二进制文件。更多详细信息请参见这里。
以下是我编写的类似的C#解决方案,它寻找给定数量的要求连续的NUL。如果IsBinary
返回false,则很可能你的文件是基于文本的。
public bool IsBinary(string filePath, int requiredConsecutiveNul = 1)
{
const int charsToCheck = 8000;
const char nulChar = '\0';
int nulCount = 0;
using (var streamReader = new StreamReader(filePath))
{
for (var i = 0; i < charsToCheck; i++)
{
if (streamReader.EndOfStream)
return false;
if ((char) streamReader.Read() == nulChar)
{
nulCount++;
if (nulCount >= requiredConsecutiveNul)
return true;
}
else
{
nulCount = 0;
}
}
}
return false;
}
using(var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
using(var reader = new BinaryReader(stream))
{
// read the first X bytes of the file
// In this example I want to check if the file is a BMP
// whose header is 424D in hex(2 bytes 6677)
string code = reader.ReadByte().ToString() + reader.ReadByte().ToString();
if (code.Equals("6677"))
{
//it's a BMP file
}
}
}
我有一个对我有效的解决方案。这是一个通用的解决方案,可以检查所有类型的二进制文件。
/// <summary>
/// This method checks whether selected file is Binary file or not.
/// </summary>
public bool CheckForBinary()
{
Stream objStream = new FileStream("your file path", FileMode.Open, FileAccess.Read);
bool bFlag = true;
// Iterate through stream & check ASCII value of each byte.
for (int nPosition = 0; nPosition < objStream.Length; nPosition++)
{
int a = objStream.ReadByte();
if (!(a >= 0 && a <= 127))
{
break; // Binary File
}
else if (objStream.Position == (objStream.Length))
{
bFlag = false; // Text File
}
}
objStream.Dispose();
return bFlag;
}
public bool IsTextFile(string FilePath)
using (StreamReader reader = new StreamReader(FilePath))
{
int Character;
while ((Character = reader.Read()) != -1)
{
if ((Character > 0 && Character < 8) || (Character > 13 && Character < 26))
{
return false;
}
}
}
return true;
}