判斷文字檔案是否UTF 8編碼

2021-07-26 01:43:21 字數 3900 閱讀 2266

utf-8編碼的文字文件,有的帶有bom (byte order mark, 位元組序標誌),即0xef, 0xbb,0xbf,有的沒有。用windows的notepad編輯的文字儲存是會自動新增bom,我們常用ue編輯器在儲存utf-8編碼的時候也會自動新增bom,notepad++預設設定中儲存utf-8編碼時是無bom的。其它文字編輯器就沒有嘗試過,有興趣的可以自己試試。

utf-8是一種多位元組編碼的字符集,表示乙個unicode字元時,它可以是1個至多個位元組。即在文字全部是ascii字元時utf-8是和ascii一致的(utf-8向下相容ascii)。utf-8位元組流如下所示:

1位元組:0******x

2位元組:110***xx 10******

3位元組:1110***x 10****** 10******

delphi:

function

isutf8format

(buffer: pchar; size: int64): boolean;

var ii: integer;

tmp: byte;

begin

result := true;

ii := 0;

while ii < size do

begin

tmp := byte(buffer[ii]);

if tmp < $80

then

//值小於0x80的為ascii字元

inc(ii)

else

if tmp < $c0 then

//值介於0x80與0xc0之間的為無效utf-8字元

begin

result := false;

break;

endelse

if tmp < $e0 then

//此範圍內為2位元組utf-8字元

begin

if ii >= size - 1

then

break;

if (byte(buffer[ii + 1]) and $c0) <> $80

then

begin

result := false;

break;

end;

inc(ii, 2);

endelse

if tmp < $f0 then

//此範圍內為3位元組utf-8字元

begin

if ii >= size - 2

then

break;

if ((byte(buffer[ii + 1]) and $c0) <> $80) or ((byte(buffer[ii + 2]) and $c0) <> $80) then

begin

result := false;

break;

end;

inc(ii, 3);

endelse

begin

result := false;

break;

end;

end;

end;

function

isutf8file

(fstream: tfilestream): string;

var fstream: tfilestream;

context: string;

begin

fstream := tfilestream.create(filename, fmopenread or fmsharedenynone);

trysetlength(context, fstream.size);

fstream.read(context[1], fstream.size);

if isutf8format(pchar(context), fstream.size) then

showmessage('是utf-8編碼');

else

showmessage('其它編碼');

finally

fstream.free;

end;

end;

c/c++

function

isutf8format

(buffer: pchar; size: int64): boolean;

var ii: integer;

tmp: byte;

begin

result := true;

ii := 0;

while ii < size do

begin

tmp := byte(buffer[ii]);

if tmp < $80

then

//值小於0x80的為ascii字元

inc(ii)

else

if tmp < $c0 then

//值介於0x80與0xc0之間的為無效utf-8字元

begin

result := false;

break;

endelse

if tmp < $e0 then

//此範圍內為2位元組utf-8字元

begin

if ii >= size - 1

then

break;

if (byte(buffer[ii + 1]) and $c0) <> $80

then

begin

result := false;

break;

end;

inc(ii, 2);

endelse

if tmp < $f0 then

//此範圍內為3位元組utf-8字元

begin

if ii >= size - 2

then

break;

if ((byte(buffer[ii + 1]) and $c0) <> $80) or ((byte(buffer[ii + 2]) and $c0) <> $80) then

begin

result := false;

break;

end;

inc(ii, 3);

endelse

begin

result := false;

break;

end;

end;

end;

function

utf8strtoansi

(fstream: tfilestream): string;

var headerstr, context:string;

begin

fstream.position := 0;

setlength(headerstr, 3);

fstream.read(headerstr[1], 3);

if headerstr = #$ef#$bb#$bf then

begin

setlength(context, fstream.size - 3);

fstream.read(context[1], fstream.size - 3);

endelse

begin

fstream.position := 0;

setlength(context, fstream.size);

fstream.read(context[1], fstream.size);

end;

result := utf8toansi(context);

end;

本文參考資料:

文字utf-8編碼判斷c/c++原始碼及utf-8編碼解釋

utf-8編碼規則解釋

判斷檔案是否是utf 8

函式名 isutf8file 日期 2011 12 01 功能 判斷檔案是否是utf 8 輸入引數 tchar strfile 返回值 int 2 表示檔案錯誤 1 表示開啟檔案錯誤 1 是utf 8 有bom 2 是utf 8 無bom 0 表示不是utf 8 int isutf8file tch...

C 判斷檔案是否文字檔案

今天fix bugs時,碰到乙個關於上傳檔案格式的問題。系統要求上傳.txt,csv格式的,這個可以根據檔案字尾名來過濾。但是如果使用者修改了字尾名來欺騙系統的話又該怎麼解決?比如a.jpg格式的改成a.txt,我現在的程式就無法識別了,雖然在後台可以彈出錯誤,但這個錯誤已經不是fs上定義的錯誤了。...

3個位元組的空txt文字檔案 utf8

csharp view plain copy system.io.filestream fs new system.io.filestream d ss.txt system.io.filemode.create fs.write new byte 0,3 fs.close 其中的efbbbf代表u...