Delphi 如何从TextFile变量获取完整的文件名?
以下代码写入名为test.txt的文件(在本例中,在当前目录中) 如何从Delphi 如何从TextFile变量获取完整的文件名?,delphi,delphi-5,Delphi,Delphi 5,以下代码写入名为test.txt的文件(在本例中,在当前目录中) 如何从F:TextFile变量中提取完整文件名?您可以使用: TTextRec(F).Name 从TextFile变量中提取指定的文件名(上例中为test.txt) 如果“完整文件名”的意思是您想要它包括完整目录,您需要告诉我们您想要它用于哪个版本的Delphi,因为更现代的版本在这方面有很多早期版本没有的功能。您可以使用: TTextRec(F).Name 从TextFile变量中提取指定的文件名(上例中为test.txt)
F:TextFile
变量中提取完整文件名?您可以使用:
TTextRec(F).Name
从TextFile变量中提取指定的文件名(上例中为test.txt)
如果“完整文件名”的意思是您想要它包括完整目录,您需要告诉我们您想要它用于哪个版本的Delphi,因为更现代的版本在这方面有很多早期版本没有的功能。您可以使用:
TTextRec(F).Name
从TextFile变量中提取指定的文件名(上例中为test.txt)
如果“完整文件名”是指您希望它包括完整目录,您需要告诉我们您希望它用于哪个版本的Delphi,因为更现代的版本在这方面有很多早期版本没有的功能。解决这个问题有两个步骤:
TextFile
对象后面的文件句柄var
FileHandle: THandle;
....
FileHandle := TTextRec(F).Handle;
步骤2的流程在MSDN上有概述。解决此问题有两个步骤:
TextFile
对象后面的文件句柄var
FileHandle: THandle;
....
FileHandle := TTextRec(F).Handle;
对于步骤2,MSDN中概述了该过程:。由于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 = $00000000;
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 define来确定Delphi是否已经有了GetFinalPathNameByHandle的导入定义——如果我发现哪个版本实际实现了这个定义,它可能会被微调
另外请注意,GetFinalPathNameByHandle仅对Windows Vista和Windows上的有效。如果尝试在以前的版本上运行,它将返回到只提取分配的文件名。如果您需要对pre Vista的支持,您可以查看David链接的页面,以获得一个应该在早期版本上运行的版本。因为这似乎是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 = $00000000;
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 define来确定Delphi是否已经有了GetFinalPathNameByHandle的导入定义——如果我发现哪个版本实际实现了这个定义,它可能会被微调
另外请注意,GetFinalPathNameByHandle仅对Windows Vista和Windows上的有效。如果尝试在以前的版本上运行,它将返回到仅提取分配的文件名。如果您需要对pre Vista的支持,您可以查看David链接的页面,以获得应在早期版本上运行的版本。
SysUtils.ExpandFileName()
已经存在很长时间了<如果需要UNC格式,也可以使用code>SysUtils.ExpandUNCFileName()。@LURD:因为我不确定这些函数实现的确切版本,所以在知道(并且可以验证)之前,我不想将它们作为选项提供它们在OP使用的版本中可用。ExpandFileName
在所有版本的Delphi中都存在。无论如何,你不应该觉得有必要迎合那些拥有古老版本的用户。工作不是帮助提问者,而是回答问题。如果询问者有一个古老的版本,那就是他们的问题。这两个函数都不是最近添加的。@HeartWare:现在我使用的是旧的Delphi 5,无论如何,我不想扩展路径,因为当前目录可能已更改。我想知道TextFile
对象是否存储了完整的文件名,如果您认为这个答案没有解决这个问题,正如您在另一个答案中所说的那样,我想您应该删除它。SysUtils.ExpandFileName()
已经存在很长时间了<如果需要UNC格式,也可以使用code>SysUtils.ExpandUNCFileName()。@LURD:因为我不确定这些函数实现的确切版本,所以在知道(并且可以验证)之前,我不想将它们作为选项提供它们在OP使用的版本中可用。ExpandFileName
在所有版本的Delphi中都存在。无论如何,你不应该觉得有必要迎合那些拥有古老版本的用户。工作不是帮助提问者,而是回答问题。如果询问者有一个古老的版本,那就是他们的问题。这两个函数都不是最近添加的。@HeartWare:现在我使用的是旧的Delphi 5,无论如何,我不想扩展路径,因为当前目录可能已更改。我想知道TextFile
对象是否存储了完整的文件名,如果您认为这个答案没有解决这个问题,正如您在另一个答案中所说的,您应该删除它。这里似乎有两个问题。1.如何从TextFile
对象获取文件名?2.如何将相对文件名扩展为绝对路径?你想让我们回答哪一个问题?请每个帖子只问一个问题。这里有细微差别。相对文件名的扩展在文件打开时由TextFile
对象完成。但是当你问这个问题时,当前目录可能已经改变了。我的建议是在调用AssignFile
之前执行扩展,并传递绝对文件名。然后不要忘记文件名,这样你就不必希望TextFile
对象记住它了。@DavidHeffernan:你说得对,但我的目标是知道分配给TextFile
对象的完整文件名。正如您所说的“当前目录可能已更改…”,因此我想知道TextFile
object是否正在某处存储完整的文件名。如果不是,我完全同意你的建议,我会在调用之前扩展路径