線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2118
推到 Plurk!
推到 Facebook!

有關XE存成TXT檔的問題

答題得分者是:herbert2
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#1 引用回覆 回覆 發表時間:2020-08-07 09:28:37 IP:36.230.xxx.xxx 未訂閱
使用版本 : XE10.4(含10.3.x)
使用 StringList.SaveToFile('123.txt', TEncoding.UTF8) 可以存成 UTF-8編碼的文字檔, 但利用記事本打開是呈現 UTF-8具BOM格式的檔案, 請問有沒有其他方式可以在存檔時, 直接為UTF-8 格式, 因為有些介面對含BOM的格式不接受, 我還得透過其他工具把它轉掉!
herbert2
尊榮會員


發表:58
回覆:640
積分:894
註冊:2004-04-16

發送簡訊給我
#2 引用回覆 回覆 發表時間:2020-08-09 13:50:10 IP:202.39.xxx.xxx 未訂閱
請參閱
https://www.itread01.com/content/1544448086.html

using (TextReader input = new StreamReader(new FileStream(@"C:\Test.properties", FileMode.Open), Encoding.UTF8))
{
using (TextWriter output = new StreamWriter(new FileStream(@"C:\Test2.lmx", FileMode.Create), Encoding.UTF8))
{
int BufferSize = 8096;
char[] buffer = new char[i];
int len;

while ((len = input.Read(buffer, 0, i)) > 0)
{
output.Write(buffer, 0, len);
}

input.Close();
}
}
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#3 引用回覆 回覆 發表時間:2020-08-10 16:19:50 IP:59.120.xxx.xxx 未訂閱
感謝 herbert2 的回覆, 這篇我在搜尋時也有看過, 只是好像是以 C++還是C#的語法, 看不太懂, 
原諒小弟能力不足, 不會改成for Delphi 語法

===================引 用 herbert2 文 章===================
請參閱
https://www.itread01.com/content/1544448086.html

using (TextReader input = new StreamReader(new FileStream(@"C:\Test.properties", FileMode.Open), Encoding.UTF8))
{
using (TextWriter output = new StreamWriter(new FileStream(@"C:\Test2.lmx", FileMode.Create), Encoding.UTF8))
{
int BufferSize = 8096;
char[] buffer = new char[i];
int len;

while ((len = input.Read(buffer, 0, i)) > 0)
{
output.Write(buffer, 0, len);
}

input.Close();
}
}
編輯記錄
P.D. 重新編輯於 2020-08-10 16:21:34, 註解 無‧
herbert2
尊榮會員


發表:58
回覆:640
積分:894
註冊:2004-04-16

發送簡訊給我
#4 引用回覆 回覆 發表時間:2020-08-13 14:09:18 IP:202.39.xxx.xxx 未訂閱
自建一個 procedure,  傳入已存在之 text 檔名及要另存的新檔名.
利用 TFileStream 的 method 讀入原 text 檔, seek 至 position 3(0起), 寫出該 posion 及之後的內容至新 text 檔 (即刪掉前 3 Bytes 的 BOM 碼).
他此例為 C#, 似乎 Read 時會自動去掉 BOM 碼, 而 Write 時不會又加入 BOM 碼, 且一次完成讀寫.
檔案若太大, 或許會有問題., 則可考慮設定 char buffer, 分多段依序讀入 buffer、將 buffer 寫出.
Delphi 的 TFileStream 於 Read 時不會改變便原 text 檔的內容,
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#5 引用回覆 回覆 發表時間:2020-08-13 17:13:56 IP:36.230.xxx.xxx 未訂閱
感謝, 我抽空再測一下建議的方式
有成功的話, 再將語法分享出來
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#6 引用回覆 回覆 發表時間:2020-08-15 21:09:57 IP:111.241.xxx.xxx 未訂閱
研究了好幾天, 也朝 FileStream方向爬文, 可能自己的功力還不到, 也顯少在system上鑽研, 仍不得其門入, 最終還是努力找到網路別人寫好移除bom的一篇程式, 直接帶入就可以用了, 分享給各位
先用 StringList.savetoFile('xxx'),
再用 RemoveBom('xxx') 就好了
底下程式碼應該會變得沒有任何縮排, 請再自行調整

function RemoveBom(filename : string) : boolean;
const UTF8_FLAG = $EFBB;
var fsRead, fsWrite : TFileStream;
w : word;
b : byte;
filename_tmp : string;
len : integer;

function WordLoHiExchange(w : Word): Word; register;
asm
XCHG AL, AH
end;
begin
result := False;
if(Fileexists(filename) = False)then exit;
fsRead := TFileStream.Create(filename, fmOpenRead or fmShareDenyNone); // or fmOpenWrite
try
fsRead.Seek(0, soFromBeginning);
fsRead.Read(w, 2);
w := WordLoHiExchange(w);
if w = UTF8_FLAG then
begin
fsRead.Read(b, 1);
len := fsRead.Size - fsRead.Position;
filename_tmp := filename 'tmp';
fsWrite := TFileStream.Create(filename_tmp, fmCreate);
fsWrite.CopyFrom(fsRead, len);
fsWrite.Free;
result := True;
end;
finally
fsRead.Free;
if result then
begin
DeleteFile(filename);
MoveFile(pChar(filename_tmp), pChar(Filename));
end;
end;
end;
Jasonwong
版主


發表:49
回覆:931
積分:581
註冊:2006-10-27

發送簡訊給我
#7 引用回覆 回覆 發表時間:2020-08-26 12:18:06 IP:125.227.xxx.xxx 未訂閱
http://firemonkeylessons.blogspot.com/2018/07/tstrings-tstringlist-utf8-bom.html

想要把 BOM 拿掉,只需要把 WriteBOM 設定為 False 即可
------
聰明的人,喜歡猜心;雖然每次都猜對了,卻失去了自己的心
傻氣的人,喜歡給心;雖然每次都被笑了,卻得到了別人的心
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#8 引用回覆 回覆 發表時間:2020-08-27 15:08:22 IP:36.226.xxx.xxx 未訂閱
哇!! 這麼簡單, 我花了好多天都找不到相關的搜尋, 網路真的浩瀚無垠, 撈不到底, 也感謝王大的提供
系統時間:2024-04-29 16:05:18
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!