谷歌翻译的
Unicode中有一个组合字符。
例如,有两种表达字符“ GA”的方法:一种用单个字符表达“ GA”的方法,以及一种将dakuten组合为“ KA” +“”的方法。
组合字符也可以在日语之外使用。例如,重音符号。
如果将使用组合字符的字符和不使用组合字符的字符混合在一起,将无法进行搜索(“ ga”和“ ka” +“””是不同的字符),这可能会造成麻烦。
所以我想统一到一侧。
统一称为Unicode规范化,有四种类型的规范化。
参考:Unicode规范化-维基百科
NFD(标准化格式D)
NFC(标准化格式C)
NFKD(归一化形式KD)
NFKC(规范格式KC)
文件名由Windows上的NFC规范化。
OSX似乎使用自己的基于NFD的实现。
因为规范化方法不同,所以在Windows和OSX之间交换文件时,会遇到意外的麻烦。
例如,在Windows上,可以使用MECSUtils.MecsNormalize函数对NFC进行标准化。
{$IFDEF MSWINDOWS}
uses MECSUtils;
{$ENDIF MSWINDOWS}
{$IFDEF MSWINDOWS}
function FileSystemStringForWin(const S: string): string;
var
W: WideString;
begin
if MECSUtils.MecsNormalize(S, W, NormalizationC) then
Result := W
else
Result := S;
end;
{$ENDIF MSWINDOWS}
问题是OSX,但是CFStringGetFileSystemRepresentation函数似乎能够执行与文件系统相同的转换。
Delphi 10.1 Berlin在System.SysUtils单元中具有StringToFileSystemString函数。
此StringToFileSystemString函数使用CFStringGetFileSystemRepresentation函数执行转换过程。
{$IFDEF MACOS}
function FileSystemStringForMac(const S: string): string;
const
MAX_PATH = 1024;
var
Bytes: TBytes;
I: Integer;
begin
SetLength(Bytes, MAX_PATH);
if System.SysUtils.StringToFileSystemString(S, Bytes) then
begin
for I := 0 to Length(Bytes) - 1 do
if Bytes[I] = 0 then
Break;
Result := TEncoding.UTF8.GetString(Bytes, 0, I);
end;
end;
{$ENDIF MACOS}
这是根据OS标准化方法转换字符串的示例。
function FileSystemString(const S: string): string;
begin
{$IFDEF MACOS}
Result := FileSystemStringForMac(S);
{$ENDIF MACOS}
{$IFDEF MSWINDOWS}
Result := FileSystemStringForWin(S);
{$ENDIF MSWINDOWS}
end;
procedure TForm1.FormCreate(Sender: TObject);
const
S1 = #$304C; // が'
S2 = #$304B + #$3099; // か゛
var
C: Char;
begin
for C in FileSystemString(S1) do
Memo1.Lines.Add(C);
for C in FileSystemString(S2) do
Memo1.Lines.Add(C);
end;