在不知道字节的实际布局或文件名格式的情况下(是否有驱动器号和路径,是否使用 UNC 路径,或者它本身只是一个文件名?),寻找文件名的边界字符串会很困难。
如果您可以假设文件名始终以驱动器号和路径开头,那么您可以一次循环一个字节的数组,直到您解码一个六字节的 UTF-16 序列,该序列由'a'
-'z'
或'A'
-之间的字符组成,'Z'
后跟':'
和'\'
人物。如果发现这种情况,请继续解码 UTF-16 序列,直到遇到解码的空字符或不是有效 UTF-16 序列的二进制值,例如:
var
Buffer: array[0..1000-1] of Byte;
I: Integer;
PCh: PWord;
Hi, Lo: Word;
Ch: Cardinal;
PStart: PWideChar;
Len: Integer;
FileName: WideString;
begin
...
I := 0;
while I <= (SizeOf(Buffer)-6) do
begin
PCh := PWord(@Buffer[I]);
if not (((PCh^ >= Ord('a')) and (PCh^ <= Ord('z'))) or ((PCh^ >= Ord('A')) and (PCh^ <= Ord('Z')))) then
begin
Inc(I);
Continue;
end;
Inc(PCh);
if PCh^ <> Ord(':') then
begin
Inc(I);
Continue;
end;
Inc(PCh);
if PCh^ <> Ord('\') then
begin
Inc(I);
Continue;
end;
PStart := PWideChar(@Buffer[I]);
Len := 0;
Inc(I, 6);
Inc(PCh);
while I <= (SizeOf(Buffer)-2) do
begin
if (PCh^ < $D800) or (PCh^ > $DFFF) then
begin
Ch := Cardinal(PCh^);
Inc(I, 2);
if Ch = 0 then Break;
Inc(Len);
end else
begin
if PCh^ > $DBFF then Break;
if (I+2) = SizeOf(Buffer) then Break;
Hi := PCh^;
Inc(PCh);
if (PCh^ < $DC00) or (PCh^ > $DFFF) then Break;
Lo := PCh^;
Ch := ((Cardinal(Hi) - $D800) * $400) + (Cardinal(Lo) - $DC00) + $10000;
if Ch > $10FFFF then Break;
Inc(I, 4);
Inc(Len, 2);
end;
end;
SetString(FileName, PStart, Len);
if Len > 0 then
begin
... use FileName as nedeed...
end;
end;
...
end;