如何从文本文件变量中获取完整文件名?
How to get the full file name from a TextFile variable?
以下代码写入名为 test.txt 的文件(在本例中,在当前目录中)
var
F : TextFile;
begin
AssignFile(F, 'test.txt');
try
Rewrite(F);
//...
finally
CloseFile(F);
end;
end;
如何从 F : TextFile
变量中提取完整的文件名?
您可以使用:
TTextRec(F).Name
从 TextFile 变量中提取 ASSIGN 的文件名(上例中的'test.txt')。
如果 "full file name" 你的意思是你想要它包括完整目录,你需要告诉我们你想要哪个版本的 Delphi,因为更现代的版本有很多这方面的功能是早期版本所没有的。
解决这个问题有两个步骤:
- 获取
TextFile
对象后面的文件句柄。
- 从该句柄中获取文件名。
对于第 1 步,您使用
var
FileHandle: THandle;
....
FileHandle := TTextRec(F).Handle;
对于第 2 步,MSDN 上概述了该过程:Obtaining a File Name From a File Handle。
由于 OP 似乎要求我最初理解的其他内容,因此我有以下答案:
{$J+}
USES Windows;
{$IFDEF UNICODE }
FUNCTION FileHandleToFileName(Handle : THandle) : STRING;
BEGIN
SetLength(Result,MAX_PATH+1);
TRY
SetLength(Result,GetFinalPathNameByHandle(Handle,@Result[LOW(Result)],LENGTH(Result),FILE_NAME_NORMALIZED))
EXCEPT
ON E:EExternalException DO SetLength(Result,0) ELSE RAISE
END;
IF COPY(Result,1,4)='\?\' THEN DELETE(Result,1,4)
END;
{$ELSE }
CONST FILE_NAME_NORMALIZED = [=10=]000000;
FUNCTION GetFinalPathNameByHandleUndefined(hFile : THandle ; lpszFilePath : PChar ; cchFilePath,dwFlags : DWORD) : DWORD; stdcall;
BEGIN
StrPCopy(lpszFilePath,'');
Result:=0
END;
FUNCTION FileHandleToFileName(Handle : THandle) : STRING;
TYPE
TGetFinalPathNameByHandle = FUNCTION(hFile : THandle ; lpszFilePath : PChar ; cchFilePath,dwFlags : DWORD) : DWORD; stdcall;
CONST
GetFinalPathNameByHandle : TGetFinalPathNameByHandle = NIL;
VAR
Err : Cardinal;
BEGIN
IF NOT Assigned(GetFinalPathNameByHandle) THEN BEGIN
GetFinalPathNameByHandle:=GetProcAddress(GetModuleHandle('kernel32'),'GetFinalPathNameByHandleA');
IF NOT Assigned(GetFinalPathNameByHandle) THEN GetFinalPathNameByHandle:=GetFinalPathNameByHandleUndefined
END;
SetLength(Result,MAX_PATH+1);
SetLength(Result,GetFinalPathNameByHandle(Handle,@Result[1],LENGTH(Result),FILE_NAME_NORMALIZED));
IF COPY(Result,1,4)='\?\' THEN DELETE(Result,1,4)
END;
{$ENDIF }
FUNCTION FileNameOf(VAR TXT : TextFile) : STRING;
VAR
Handle : THandle;
BEGIN
Handle:=TTextRec(TXT).Handle;
Result:=FileHandleToFileName(Handle);
IF Result='' THEN Result:=StrPas(TTextRec(TXT).Name)
END;
我目前使用 UNICODE 定义来确定 Delphi 是否已经有 GetFinalPathNameByHandle 的导入定义 - 如果我发现哪个版本实际实现了这个定义,它可能会被微调。
另请注意,GetFinalPathNameByHandle 仅对 Windows Vista 及更高版本有效。如果尝试在以前的版本上 运行,它将回退到简单地提取已分配的文件名。如果您需要对 pre-Vista 的支持,您可以查看 David 链接到的页面以获得适用于早期版本的版本。
以下代码写入名为 test.txt 的文件(在本例中,在当前目录中)
var
F : TextFile;
begin
AssignFile(F, 'test.txt');
try
Rewrite(F);
//...
finally
CloseFile(F);
end;
end;
如何从 F : TextFile
变量中提取完整的文件名?
您可以使用:
TTextRec(F).Name
从 TextFile 变量中提取 ASSIGN 的文件名(上例中的'test.txt')。
如果 "full file name" 你的意思是你想要它包括完整目录,你需要告诉我们你想要哪个版本的 Delphi,因为更现代的版本有很多这方面的功能是早期版本所没有的。
解决这个问题有两个步骤:
- 获取
TextFile
对象后面的文件句柄。 - 从该句柄中获取文件名。
对于第 1 步,您使用
var
FileHandle: THandle;
....
FileHandle := TTextRec(F).Handle;
对于第 2 步,MSDN 上概述了该过程:Obtaining a File Name From a File Handle。
由于 OP 似乎要求我最初理解的其他内容,因此我有以下答案:
{$J+}
USES Windows;
{$IFDEF UNICODE }
FUNCTION FileHandleToFileName(Handle : THandle) : STRING;
BEGIN
SetLength(Result,MAX_PATH+1);
TRY
SetLength(Result,GetFinalPathNameByHandle(Handle,@Result[LOW(Result)],LENGTH(Result),FILE_NAME_NORMALIZED))
EXCEPT
ON E:EExternalException DO SetLength(Result,0) ELSE RAISE
END;
IF COPY(Result,1,4)='\?\' THEN DELETE(Result,1,4)
END;
{$ELSE }
CONST FILE_NAME_NORMALIZED = [=10=]000000;
FUNCTION GetFinalPathNameByHandleUndefined(hFile : THandle ; lpszFilePath : PChar ; cchFilePath,dwFlags : DWORD) : DWORD; stdcall;
BEGIN
StrPCopy(lpszFilePath,'');
Result:=0
END;
FUNCTION FileHandleToFileName(Handle : THandle) : STRING;
TYPE
TGetFinalPathNameByHandle = FUNCTION(hFile : THandle ; lpszFilePath : PChar ; cchFilePath,dwFlags : DWORD) : DWORD; stdcall;
CONST
GetFinalPathNameByHandle : TGetFinalPathNameByHandle = NIL;
VAR
Err : Cardinal;
BEGIN
IF NOT Assigned(GetFinalPathNameByHandle) THEN BEGIN
GetFinalPathNameByHandle:=GetProcAddress(GetModuleHandle('kernel32'),'GetFinalPathNameByHandleA');
IF NOT Assigned(GetFinalPathNameByHandle) THEN GetFinalPathNameByHandle:=GetFinalPathNameByHandleUndefined
END;
SetLength(Result,MAX_PATH+1);
SetLength(Result,GetFinalPathNameByHandle(Handle,@Result[1],LENGTH(Result),FILE_NAME_NORMALIZED));
IF COPY(Result,1,4)='\?\' THEN DELETE(Result,1,4)
END;
{$ENDIF }
FUNCTION FileNameOf(VAR TXT : TextFile) : STRING;
VAR
Handle : THandle;
BEGIN
Handle:=TTextRec(TXT).Handle;
Result:=FileHandleToFileName(Handle);
IF Result='' THEN Result:=StrPas(TTextRec(TXT).Name)
END;
我目前使用 UNICODE 定义来确定 Delphi 是否已经有 GetFinalPathNameByHandle 的导入定义 - 如果我发现哪个版本实际实现了这个定义,它可能会被微调。
另请注意,GetFinalPathNameByHandle 仅对 Windows Vista 及更高版本有效。如果尝试在以前的版本上 运行,它将回退到简单地提取已分配的文件名。如果您需要对 pre-Vista 的支持,您可以查看 David 链接到的页面以获得适用于早期版本的版本。