// 作者:袁曉輝
//  
// // // // // //
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,對于片斷,我們就無能為力了:)
新聞熱點
疑難解答