IDFTP DirExists 和 MakeDir
IDFTP DirExists and MakeDir
我正在使用 Indy IDFTP 创建目录。我需要找到一种可靠的方法来确定目录是否存在,如果不存在,则调用 MakeDir。我尝试了以下代码,但是调用 List 时没有发生异常,因此即使目录当时不存在,也没有执行 MakeDir。如何判断一个目录是否存在,如果不存在则创建该目录?
{ Check to see if the '/public_html/XXX/' + iDomain + 'Thumbnails' directory exists }
try
IdFTP1.List(nil, '/public_html/XXX/' + iDomain + 'Thumbnails', False);
except
on e: EIdReplyRFCError do
begin
{ '/public_html/XXX/' + iDomain + 'Thumbnails' directory does not exist }
StatusBar1.SimpleText := 'Making thumbnail directory...';
StatusBar1.Update;
iFolder := '/public_html/XXX/' + iDomain;
{ Change directory to /public_html/XXX/iDomain }
IdFTP1.ChangeDir(iFolder);
iFolder := 'Thumbnails';
{ Create FTP Directory for Thumbnails }
IdFTP1.MakeDir(iFolder);
end;
end;
在我测试期间目录不存在但在运行时 e 为零?我的做法是否正确?
如果 TIdFTP.List()
没有引发异常,则 FTP 服务器很可能返回 450
回复代码,即 "Requested file action not taken"。 TIdFTP.InternalGet()
(由 TIdFTP.List()
、TIdFTP.ExtListDir()
和 TIdFTP.Get()
使用)不会将 450
视为错误条件,因为某些服务器(如 Ericsson Switch FTP) 发送 450
列出一个空但存在的目录的内容,因此没有要发送的列表数据。但是,当请求的目录不存在时,某些服务器会发送 450
。 TIdFTP.List()
不尝试区分。但是,如果 TIdFTP.List()
没有引发异常,您可以查看 TIdFTP.LastCmdResult
属性 以根据需要手动区分。
此外,您不能仅仅依靠引发异常这一事实来表示文件夹不存在。可能会发生任何数量的错误。您必须实际查看错误并采取相应措施,例如:
var
Exists: Boolean;
try
IdFTP1.List(nil, '/public_html/XXX/' + iDomain + 'Thumbnails', False);
Exists := True;
if IdFTP1.LastCmdResult.NumericCode = 450 then
begin
if (IdFTP1.LastCmdResult.Text.Text has a message like 'No such file or directory' or similar) then begin
Exists := False;
end;
// look for other possible text messages...
end;
except
on e: EIdReplyRFCError do
begin
if (e.ErrorCode <> 550) or (e.Message does not have a message like 'Directory not found' or similar) then begin
raise;
end;
Exists := false;
end;
end;
if not Exists then
begin
{ '/public_html/XXX/' + iDomain + 'Thumbnails' directory does not exist }
StatusBar1.SimpleText := 'Making thumbnail directory...';
StatusBar1.Update;
iFolder := '/public_html/XXX/' + iDomain;
{ Change directory to /public_html/XXX/iDomain }
IdFTP1.ChangeDir(iFolder);
iFolder := 'Thumbnails';
{ Create FTP Directory for Thumbnails }
IdFTP1.MakeDir(iFolder);
end;
更好的方法是:
ChangeDir()
直接到目标目录,看是否失败。如果是这样,开始通过路径向后走,为每个父目录调用 ChangeDir()
直到最后成功,然后使用 MakeDir()
和 ChangeDir()
返回路径以创建丢失的子目录根据需要。
从路径中的第一个目录开始 ChangeDir()
,然后 List()
查看下一个子文件夹是否存在,MakeDir()
如果需要它,然后 ChangeDir()
到它,并根据需要重复直到到达目标目录。
欢迎来到 FTP。它不是一个非常有效的目录管理协议。
这里是上传文件夹的方法。 Source.
{
Upload the LocalDir to an FTP server, in the RemoteDir.
If RemoteDir does not exist it is created.
All files and subfolders of LocalDir will be uploaded.
FTP parameters (username, password, server) must be already provided.
The caller must connnect to the server before calling UploadFolderToFtp and disconnect after that }
procedure UploadFolderToFtp(FTP: TIdFTP; LocalDir, RemoteDir, Filter: string);
procedure GoToSubDir(SubDir: string);
VAR
details, nodetails: TStringList;
k: Integer;
begin
details := TStringList.Create; //get folder contents from ftp. one with details, one without
nodetails := TStringList.Create;
TRY
FTP.List(details, '', True);
FTP.List(nodetails, '', False);
//we only want to have directories in the list (without '.' and '..')
for k := details.Count - 1 downto 0 do
if details.Strings[k] <> '' then
if (PosInsensitive('dir', details.Strings[k]) < 1)
OR (nodetails.Strings[k] = '.')
OR (nodetails.Strings[k] = '..') then
begin
details.Delete(k);
nodetails.Delete(k);
end;
//if our directory does not exists on the server, create it
if nodetails.IndexOf(SubDir) = -1
then FTP.MakeDir(SubDir);
FINALLY
FreeAndNil(Details);
FreeAndNil(nodetails);
END;
FTP.ChangeDir(SubDir); //change into next directory on server
end;
procedure uploadDir(dir: string);
VAR
s: string;
List: TStringList;
begin
List:= ListDirectoriesOf(dir, FALSE, FALSE); //iterate through subdirectories
for s in List DO
begin
GoToSubDir(s);
uploadDir(dir + s + '\'); //and also locally go into the next subfolder
FTP.ChangeDirUp; //we have to go one directory up after leaving the recursion
end;
FreeAndNil(List);
List:= ListFilesOf(dir, Filter, FALSE, FALSE); //iterate through files
for s in List DO
begin
Assert(s > '', 'File name should not be empty!');
FTP.Put(dir + s, s); //if it's only a file, upload it to the current directory;
end;
FreeAndNil(List);
end;
VAR
subdir, dir: string;
begin
//does not matter if RemoteDir is like 'dir\dir' or 'dir/dir'
dir := StringReplace(RemoteDir, '\', '/', [rfReplaceAll]);
if dir <> '' then
begin
if dir[1] = '/' then Delete(dir, 1, 1); //remove first '/' if there's one
if dir[Length(dir)] <> '/' then dir := dir + '/'; // add a '/' at the end
//loop through our remote-directories
WHILE Pos('/', dir) > 0 DO
begin
SubDir:= system.Copy(dir, 1, Pos('/', dir) - 1);
//if our directory does not exists on the server, we create it
GoToSubDir(SubDir);
//remove first directory from path ('your/directory/subdir/' --> 'directory/subdir/')
Delete(dir, 1, Pos('/', dir));
end;
end;
dir := LocalDir;
if dir[Length(dir)] <> '\'
then dir := dir + '\';
uploadDir(dir); // begin the upload
end;
procedure TfrmFTP.Button1Click(Sender: TObject);
begin
if Connect {Set parameters for FTP and connect to server }
then UploadFolderToFtp(ftp, 'c:\test\', RemoteDir, '*.*')
else SwMessage('Cannot connect to '+ FTP.ServerHOST);
Disconnect;
end;
--
ListDirectoriesOf & ListFilesOf 是 returns 指定文件夹的 subdirectories/files 的函数(returns non-full 路径)
简单的解决方案是
IdFTP.ChangeDir('/www/image/catalog/'); // connect to to directory where you want to add folder
try
IdFTP.MakeDir(new_Dir_name); // try to create folder
IdFTP.ChangeDir('/www/image/catalog/' + new_Dir_name ); // connect to new folder
except
IdFTP.ChangeDir('/www/image/catalog/' + new_Dir_name ); // if folder exist just connect to folder which exist
end;
我正在使用 Indy IDFTP 创建目录。我需要找到一种可靠的方法来确定目录是否存在,如果不存在,则调用 MakeDir。我尝试了以下代码,但是调用 List 时没有发生异常,因此即使目录当时不存在,也没有执行 MakeDir。如何判断一个目录是否存在,如果不存在则创建该目录?
{ Check to see if the '/public_html/XXX/' + iDomain + 'Thumbnails' directory exists }
try
IdFTP1.List(nil, '/public_html/XXX/' + iDomain + 'Thumbnails', False);
except
on e: EIdReplyRFCError do
begin
{ '/public_html/XXX/' + iDomain + 'Thumbnails' directory does not exist }
StatusBar1.SimpleText := 'Making thumbnail directory...';
StatusBar1.Update;
iFolder := '/public_html/XXX/' + iDomain;
{ Change directory to /public_html/XXX/iDomain }
IdFTP1.ChangeDir(iFolder);
iFolder := 'Thumbnails';
{ Create FTP Directory for Thumbnails }
IdFTP1.MakeDir(iFolder);
end;
end;
在我测试期间目录不存在但在运行时 e 为零?我的做法是否正确?
如果 TIdFTP.List()
没有引发异常,则 FTP 服务器很可能返回 450
回复代码,即 "Requested file action not taken"。 TIdFTP.InternalGet()
(由 TIdFTP.List()
、TIdFTP.ExtListDir()
和 TIdFTP.Get()
使用)不会将 450
视为错误条件,因为某些服务器(如 Ericsson Switch FTP) 发送 450
列出一个空但存在的目录的内容,因此没有要发送的列表数据。但是,当请求的目录不存在时,某些服务器会发送 450
。 TIdFTP.List()
不尝试区分。但是,如果 TIdFTP.List()
没有引发异常,您可以查看 TIdFTP.LastCmdResult
属性 以根据需要手动区分。
此外,您不能仅仅依靠引发异常这一事实来表示文件夹不存在。可能会发生任何数量的错误。您必须实际查看错误并采取相应措施,例如:
var
Exists: Boolean;
try
IdFTP1.List(nil, '/public_html/XXX/' + iDomain + 'Thumbnails', False);
Exists := True;
if IdFTP1.LastCmdResult.NumericCode = 450 then
begin
if (IdFTP1.LastCmdResult.Text.Text has a message like 'No such file or directory' or similar) then begin
Exists := False;
end;
// look for other possible text messages...
end;
except
on e: EIdReplyRFCError do
begin
if (e.ErrorCode <> 550) or (e.Message does not have a message like 'Directory not found' or similar) then begin
raise;
end;
Exists := false;
end;
end;
if not Exists then
begin
{ '/public_html/XXX/' + iDomain + 'Thumbnails' directory does not exist }
StatusBar1.SimpleText := 'Making thumbnail directory...';
StatusBar1.Update;
iFolder := '/public_html/XXX/' + iDomain;
{ Change directory to /public_html/XXX/iDomain }
IdFTP1.ChangeDir(iFolder);
iFolder := 'Thumbnails';
{ Create FTP Directory for Thumbnails }
IdFTP1.MakeDir(iFolder);
end;
更好的方法是:
ChangeDir()
直接到目标目录,看是否失败。如果是这样,开始通过路径向后走,为每个父目录调用ChangeDir()
直到最后成功,然后使用MakeDir()
和ChangeDir()
返回路径以创建丢失的子目录根据需要。从路径中的第一个目录开始
ChangeDir()
,然后List()
查看下一个子文件夹是否存在,MakeDir()
如果需要它,然后ChangeDir()
到它,并根据需要重复直到到达目标目录。
欢迎来到 FTP。它不是一个非常有效的目录管理协议。
这里是上传文件夹的方法。 Source.
{
Upload the LocalDir to an FTP server, in the RemoteDir.
If RemoteDir does not exist it is created.
All files and subfolders of LocalDir will be uploaded.
FTP parameters (username, password, server) must be already provided.
The caller must connnect to the server before calling UploadFolderToFtp and disconnect after that }
procedure UploadFolderToFtp(FTP: TIdFTP; LocalDir, RemoteDir, Filter: string);
procedure GoToSubDir(SubDir: string);
VAR
details, nodetails: TStringList;
k: Integer;
begin
details := TStringList.Create; //get folder contents from ftp. one with details, one without
nodetails := TStringList.Create;
TRY
FTP.List(details, '', True);
FTP.List(nodetails, '', False);
//we only want to have directories in the list (without '.' and '..')
for k := details.Count - 1 downto 0 do
if details.Strings[k] <> '' then
if (PosInsensitive('dir', details.Strings[k]) < 1)
OR (nodetails.Strings[k] = '.')
OR (nodetails.Strings[k] = '..') then
begin
details.Delete(k);
nodetails.Delete(k);
end;
//if our directory does not exists on the server, create it
if nodetails.IndexOf(SubDir) = -1
then FTP.MakeDir(SubDir);
FINALLY
FreeAndNil(Details);
FreeAndNil(nodetails);
END;
FTP.ChangeDir(SubDir); //change into next directory on server
end;
procedure uploadDir(dir: string);
VAR
s: string;
List: TStringList;
begin
List:= ListDirectoriesOf(dir, FALSE, FALSE); //iterate through subdirectories
for s in List DO
begin
GoToSubDir(s);
uploadDir(dir + s + '\'); //and also locally go into the next subfolder
FTP.ChangeDirUp; //we have to go one directory up after leaving the recursion
end;
FreeAndNil(List);
List:= ListFilesOf(dir, Filter, FALSE, FALSE); //iterate through files
for s in List DO
begin
Assert(s > '', 'File name should not be empty!');
FTP.Put(dir + s, s); //if it's only a file, upload it to the current directory;
end;
FreeAndNil(List);
end;
VAR
subdir, dir: string;
begin
//does not matter if RemoteDir is like 'dir\dir' or 'dir/dir'
dir := StringReplace(RemoteDir, '\', '/', [rfReplaceAll]);
if dir <> '' then
begin
if dir[1] = '/' then Delete(dir, 1, 1); //remove first '/' if there's one
if dir[Length(dir)] <> '/' then dir := dir + '/'; // add a '/' at the end
//loop through our remote-directories
WHILE Pos('/', dir) > 0 DO
begin
SubDir:= system.Copy(dir, 1, Pos('/', dir) - 1);
//if our directory does not exists on the server, we create it
GoToSubDir(SubDir);
//remove first directory from path ('your/directory/subdir/' --> 'directory/subdir/')
Delete(dir, 1, Pos('/', dir));
end;
end;
dir := LocalDir;
if dir[Length(dir)] <> '\'
then dir := dir + '\';
uploadDir(dir); // begin the upload
end;
procedure TfrmFTP.Button1Click(Sender: TObject);
begin
if Connect {Set parameters for FTP and connect to server }
then UploadFolderToFtp(ftp, 'c:\test\', RemoteDir, '*.*')
else SwMessage('Cannot connect to '+ FTP.ServerHOST);
Disconnect;
end;
--
ListDirectoriesOf & ListFilesOf 是 returns 指定文件夹的 subdirectories/files 的函数(returns non-full 路径)
简单的解决方案是
IdFTP.ChangeDir('/www/image/catalog/'); // connect to to directory where you want to add folder
try
IdFTP.MakeDir(new_Dir_name); // try to create folder
IdFTP.ChangeDir('/www/image/catalog/' + new_Dir_name ); // connect to new folder
except
IdFTP.ChangeDir('/www/image/catalog/' + new_Dir_name ); // if folder exist just connect to folder which exist
end;