// 作者:袁晓辉
//
// // // // // //
using system;
using system.text;
using system.io;
namespace farproc.text
{
/// <summary>
/// 用于取得一个文本文件的编码方式(encoding)。
/// </summary>
public class txtfileencoding
{
public txtfileencoding()
{
//
// todo: 在此处添加构造函数逻辑
//
}
/// <summary>
/// 取得一个文本文件的编码方式。如果无法在文件头部找到有效的前导符,encoding.default将被返回。
/// </summary>
/// <param name="filename">文件名。</param>
/// <returns></returns>
public static encoding getencoding(string filename)
{
return getencoding(filename, encoding.default);
}
/// <summary>
/// 取得一个文本文件流的编码方式。
/// </summary>
/// <param name="stream">文本文件流。</param>
/// <returns></returns>
public static encoding getencoding(filestream stream)
{
return getencoding(stream, encoding.default);
}
/// <summary>
/// 取得一个文本文件的编码方式。
/// </summary>
/// <param name="filename">文件名。</param>
/// <param name="defaultencoding">默认编码方式。当该方法无法从文件的头部取得有效的前导符时,将返回该编码方式。</param>
/// <returns></returns>
public static encoding getencoding(string filename, encoding defaultencoding)
{
filestream fs = new filestream(filename, filemode.open);
encoding targetencoding = getencoding(fs, defaultencoding);
fs.close();
return targetencoding;
}
/// <summary>
/// 取得一个文本文件流的编码方式。
/// </summary>
/// <param name="stream">文本文件流。</param>
/// <param name="defaultencoding">默认编码方式。当该方法无法从文件的头部取得有效的前导符时,将返回该编码方式。</param>
/// <returns></returns>
public static encoding getencoding(filestream stream, encoding defaultencoding)
{
encoding targetencoding = defaultencoding;
if(stream != null && stream.length >= 2)
{
//保存文件流的前4个字节
byte byte1 = 0;
byte byte2 = 0;
byte byte3 = 0;
byte byte4 = 0;
//保存当前seek位置
long origpos = stream.seek(0, seekorigin.begin);
stream.seek(0, seekorigin.begin);
int nbyte = stream.readbyte();
byte1 = convert.tobyte(nbyte);
byte2 = convert.tobyte(stream.readbyte());
if(stream.length >= 3)
{
byte3 = convert.tobyte(stream.readbyte());
}
if(stream.length >= 4)
{
byte4 = convert.tobyte(stream.readbyte());
}
//根据文件流的前4个字节判断encoding
//unicode {0xff, 0xfe};
//be-unicode {0xfe, 0xff};
//utf8 = {0xef, 0xbb, 0xbf};
if(byte1 == 0xfe && byte2 == 0xff)//unicodebe
{
targetencoding = encoding.bigendianunicode;
}
if(byte1 == 0xff && byte2 == 0xfe && byte3 != 0xff)//unicode
{
targetencoding = encoding.unicode;
}
if(byte1 == 0xef && byte2 == 0xbb && byte3 == 0xbf)//utf8
{
targetencoding = encoding.utf8;
}
//恢复seek位置
stream.seek(origpos, seekorigin.begin);
}
return targetencoding;
}
}
}
由于在gb2312和utf7编码都没有bom,所以需要指定一个默认的encoding,在找不到合法的bom时,将返回这个encoding。有谁知道如何区分gb2312和utf7编码txt文件的方法,也请告诉我。 由于只是static方法,所以不用new,直接通过类名调用方法,使用起来也很简单。
using system;
using farproc.text;
using system.text;
using system.io;
namespace consoleapplication1
{
/// <summary>
/// class1 的摘要说明。
/// </summary>
class class1
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[stathread]
static void
{
//
// todo: 在此处添加代码以启动应用程序
//
string filename = @"e:/a.txt";
//生成一个big endian unicode编码格式的文本文件
streamwriter sw = new streamwriter(filename, false, encoding.bigendianunicode);//你可以试试其他编码,比如encoding.getencoding("gb2312")或utf8
sw.write("这是一个string");
sw.close();
//读取
encoding fileencoding = txtfileencoding.getencoding(filename, encoding.getencoding("gb2312"));//取得这txt文件的编码
console.writeline("这个文本文件的编码为:" + fileencoding.encodingname);
streamreader sr = new streamreader(filename, fileencoding);//用该编码创建streamreader
//用下面的方法虽然可以让系统自动判断文本文件的编码格式,但是我们无法取得该文本文件的编码
//sr.currentencoding永远为 unicode(utf-8)
//streamreader sr = new streamreader(filename, true);
//console.writeline("这个文本文件的编码为:" + sr.currentencoding.encodingname);
console.writeline("这个文本文件的内容为:" + sr.readtoend());
sr.close();
console.readline();
}
}
}
.net下的string永远是unicode的,所以只能判断txt文件的encoding。对于byte[],只有自己知道它的encoding才能转换为string 转换为其他编码的byte[],一个例外是把整个txt文件通过stream读入byte[]后也可以根据它的前几个字节判断encoding,对于片断,我们就无能为力了:)
新闻热点
疑难解答