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******xdelphi:2位元組:110***xx 10******
3位元組:1110***x 10****** 10******
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...