Create a UTF8 file without BOM with Inno Setup (Unicode version)
我必须阅读和修改一些JSON文件。 文件编码必须为不带BOM的UTF8,否则将不接受JSON文件。
我尝试了以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | const Utf8Bom = #$EF#$BB#$BF; Utf16BomLE = #$FF#$FE; // little endian // Utf16BomBE = #$FE#$FF; // big endian // Utf16Bom = Utf16BomBE; CP_UTF16 = 1200; CP_UTF8 = 65001; function WideStringToString (const wStr: string; codePage: Word): string; var len: Integer; begin len := WideCharToMultiByte (codePage, 0, wStr, -1, '', 0, 0, 0); if len > 0 then begin SetLength (Result, len-1); WideCharToMultiByte (codePage, 0, wStr, -1, Result, Length (Result), 0, 0); end; end; function ClearBom(const s, sig: string): string; var i, n, len: Integer; begin Result := s; len := Length (sig); n := 0; if (len> 0) and (Length (Result)> len) then repeat for i := 1 to len do if Result [1] = sig [i] then begin Delete (Result, 1, 1); Break; end; n := n + 1; until (n = len) or (Result = ''); end; function ConvertUtf16(const SourceStr: string; codePage: Word): string; var wStr: string; begin try wStr := ClearBom(SourceStr, Utf16Bom); Result := WideStringToString(wStr, codePage); finally SetLength(wStr, 0); end; end; function Utf16ToUtf8(const SourceStr: string): string; begin Result := ConvertUtf16(SourceStr, CP_UTF8); end; function JSONSaveFile(const Filename: String; s: String): Boolean; var fs: TFileStream; i, len : Integer; begin i := 1; len := Length(s) If len > 0 then begin try try fs := TFileStream.Create(Filename, fmCreate or f mShareExclusive); fs.Seek(0, 0); while (s[i] <> #0) and (i < len) do begin fs.WriteBuffer(s[i],CharLength(s,i)); i := i + CharLength(s,i); end; Result := True; except Log('EXCEPTION RAISED in JSONSaveFile: '+Filename); end; finally fs.free; end; end; end; |
我只得到ANSI编码的文件。 诸如
还是使用
怎么解决呢?
使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | const CP_UTF8 = 65001; function WideCharToMultiByte(CodePage: UINT; dwFlags: DWORD; lpWideCharStr: string; cchWideChar: Integer; lpMultiByteStr: AnsiString; cchMultiByte: Integer; lpDefaultCharFake: Integer; lpUsedDefaultCharFake: Integer): Integer; external '[email protected] stdcall'; function GetStringAsUtf8(S: string): AnsiString; var Len: Integer; begin Len := WideCharToMultiByte(CP_UTF8, 0, S, Length(S), Result, 0, 0, 0); SetLength(Result, Len); WideCharToMultiByte(CP_UTF8, 0, S, Length(S), Result, Len, 0, 0); end; function SaveStringToUTF8FileWithoutBOM(FileName: string; S: string): Boolean; var Utf8: AnsiString; begin Utf8 := GetStringAsUtf8(S); Result := SaveStringToFile(FileName, Utf8, False); end; |
您必须使用Inno Setup的Unicode版本(Inno Setup 6唯一的版本)。
也可以看看:
-
LoadStringFromFileInCP 和LoadStringsFromFileInCP 在以下功能中起作用:
Inno Setup-将字符串数组转换为Unicode并转换回ANSI - Inno Setup替换不带BOM的UTF-8文件中的字符串