FTP 会话

WinINet 使应用程序能够在 ftp 服务器上导航和操作目录和文件。 由于 CERN 代理不支持 FTP,因此独占使用 CERN 代理的应用程序必须使用 InternetOpenUrl 函数。 有关如何使用 InternetOpenUrl 的详细信息,请参阅 直接访问 URL

若要开始 FTP 会话,请使用 InternetConnect 创建会话句柄。

使用 WinINet 可以在 FTP 服务器上执行以下操作:

  • 在目录之间导航。
  • 枚举、创建、删除和重命名目录。
  • 重命名、上传、下载和删除文件。

导航由 FtpGetCurrentDirectoryFtpSetCurrentDirectory 函数提供。 这些函数利用以前调用 InternetConnect 创建的会话句柄来确定应用程序当前所在的目录,或者更改为其他子目录。

目录枚举是使用 FtpFindFirstFileInternetFindNextFile 函数执行的。 FtpFindFirstFile 使用 InternetConnect 创建的会话句柄查找与给定搜索条件匹配的第一个文件,并返回一个句柄以继续目录枚举。 InternetFindNextFile 使用 FtpFindFirstFile 返回的句柄返回与原始搜索条件匹配的下一个文件。 应用程序应继续调用 InternetFindNextFile ,直到目录中没有其他文件。

使用 FtpCreateDirectory 函数创建新目录。 此函数使用 InternetConnect 创建的会话句柄,并创建由传递给函数的字符串指定的目录。 字符串可以包含相对于当前目录的目录名称,也可以包含完全限定的目录路径。

若要重命名文件或目录,应用程序可以调用 FtpRenameFile。 此函数将原始名称替换为传递给函数的新名称。 文件或目录的名称可以是相对于当前目录的名称,也可以是完全限定的名称。

若要在 FTP 服务器上上传或放置文件,应用程序可以使用 FtpPutFileFtpOpenFile (以及 InternetWriteFile) 。 如果文件已在本地存在,则可以使用 FtpPutFile;如果需要将数据写入 FTP 服务器上的文件,则可以使用 FtpOpenFileInternetWriteFile

若要下载或获取文件,应用程序可以使用 FtpGetFileFtpOpenFile (与 InternetReadFile) 。 FtpGetFile 用于从 FTP 服务器检索文件并将其存储在本地,而 FtpOpenFileInternetReadFile 可用于控制下载的信息 (的位置,例如,应用程序可以在编辑框中显示信息) 。

使用 FtpDeleteFile 函数删除 FTP 服务器上的文件。 此函数从 FTP 服务器中删除相对于当前目录或完全限定文件名的文件名。 FtpDeleteFile 需要 InternetConnect 返回的会话句柄。

FTP 函数句柄

若要正常工作,FTP 函数需要某些类型的 HINTERNET 句柄。 必须按特定顺序创建这些句柄,从 InternetOpen 创建的根句柄开始。 然后,InternetConnect 可以创建 FTP 会话句柄。

下图显示了依赖于 InternetConnect 返回的 FTP 会话句柄的函数。 带阴影的框表示返回 HINTERNET 句柄的函数,而普通框表示使用由它们所依赖的函数创建的 HINTERNET 句柄的函数。

依赖于 Internetconnect 返回的 ftp 会话句柄的 ftp 函数

下图显示了返回 HINTERNET 句柄的两个函数和依赖于它们的函数。 带阴影的框表示返回 HINTERNET 句柄的函数,而普通框表示使用由它们所依赖的函数创建的 HINTERNET 句柄的函数。

返回 hinternet 句柄的 ftp 函数

有关详细信息,请参阅 HINTERNET 句柄

将 WinINet 函数用于 FTP 会话

FTP 会话期间使用以下函数。 CERN 代理无法识别这些函数。 必须通过 CERN 代理运行的应用程序应使用 InternetOpenUrl 并直接访问资源。 有关直接资源访问的详细信息,请参阅 直接访问 URL

函数 说明
FtpCreateDirectory 在服务器上创建新目录。 此函数需要 InternetConnect 创建的句柄。
FtpDeleteFile 从服务器中删除文件。 此函数需要 InternetConnect 创建的句柄。
FtpFindFirstFile 在当前目录中启动文件枚举或文件搜索。 此函数需要 InternetConnect 创建的句柄。
FtpGetCurrentDirectory 返回服务器上客户端的当前目录。 此函数需要 InternetConnect 创建的句柄。
FtpGetFile 从服务器检索文件。 此函数需要 InternetConnect 创建的句柄。
FtpOpenFile 启动对服务器上的文件进行读取或写入的访问。 此函数需要 InternetConnect 创建的句柄。
FtpPutFile 将文件写入服务器。 此函数需要 InternetConnect 创建的句柄。
FtpRemoveDirectory 删除服务器上的目录。 此函数需要 InternetConnect 创建的句柄。
FtpRenameFile 重命名服务器上的文件。 此函数需要 InternetConnect 创建的句柄。
FtpSetCurrentDirectory 更改服务器上的客户端当前目录。 此函数需要 InternetConnect 创建的句柄。
InternetWriteFile 将数据写入服务器上的打开的文件。 此函数需要 FtpOpenFile 创建的句柄。

 

启动 FTP 会话

应用程序通过在 InternetOpen 创建的句柄上调用 InternetConnect 来建立 FTP 会话。 InternetConnect 需要服务器名称、端口号、用户名、密码和服务类型 (必须设置为INTERNET_SERVICE_FTP) 。 对于被动 FTP 语义,应用程序还必须设置 INTERNET_FLAG_PASSIVE 标志。

INTERNET_DEFAULT_FTP_PORT和INTERNET_INVALID_PORT_NUMBER值可用于端口号。 INTERNET_DEFAULT_FTP_PORT使用默认的 FTP 端口,但仍必须设置服务类型。 INTERNET_INVALID_PORT_NUMBER为指示的服务类型使用默认值。

用户名和密码的值可以设置为 NULL。 如果两个值都设置为 NULL则 InternetConnect 将“anonymous”用作用户名,并将用户的电子邮件地址用作密码。 如果仅将密码设置为 NULL,则传递给 InternetConnect 的用户名将用作用户名,空字符串用于密码。 如果两个值都不为 NULL,则使用提供给 InternetConnect 的 用户名和密码。

枚举目录

枚举 FTP 服务器上的目录需要通过 FtpFindFirstFile 创建句柄。 此句柄是由 InternetConnect 创建的会话句柄的分支。 FtpFindFirstFile 查找服务器上的第一个文件或目录,并在 WIN32_FIND_DATA 结构中返回该文件或目录。 使用 InternetFindNextFile ,直到返回 ERROR_NO_MORE_FILES。 此方法查找服务器上的所有后续文件和目录。 有关 InternetFindNextFile 的详细信息,请参阅 查找下一个文件

若要确定由 FtpFindFirstFile 或 InternetFindNextFile 检索到的文件是否为目录,检查 WIN32_FIND_DATA 结构的 dwFileAttributes 成员以查看它是否等于 FILE_ATTRIBUTE_DIRECTORY。

如果应用程序在 FTP 服务器上进行更改,或者 FTP 服务器频繁更改,则应在 FtpFindFirstFile 中设置INTERNET_FLAG_NO_CACHE_WRITEINTERNET_FLAG_RELOAD标志。 这些标志可确保从 FTP 服务器检索的目录信息是最新的。

应用程序完成目录枚举后,应用程序必须在 FtpFindFirstFile 创建的句柄上调用 InternetCloseHandle。 在该句柄关闭之前,应用程序无法在 InternetConnect 创建的会话句柄上再次调用 FtpFindFirstFile。 如果在关闭对同一函数的上一次调用之前在同一会话句柄上调用 FtpFindFirstFile ,则函数将失败,返回 ERROR_FTP_TRANSFER_IN_PROGRESS

以下示例将 FTP 目录的内容枚举到列表框控件中。 hConnection 参数是 InternetConnect 函数在建立 FTP 会话后返回的句柄。 可以在 处理错误主题中找到此示例中引用的 InternetErrorOut 函数的示例源代码。

#include <windows.h>
#include <strsafe.h>
#include <wininet.h>

#pragma comment(lib, "wininet.lib")
#pragma comment(lib, "user32.lib")

#define  FTP_FUNCTIONS_BUFFER_SIZE          MAX_PATH+8

BOOL WINAPI DisplayFtpDir(
                           HWND hDlg,
                           HINTERNET hConnection,
                           DWORD dwFindFlags,
                           int nListBoxId )
{
  WIN32_FIND_DATA dirInfo;
  HINTERNET       hFind;
  DWORD           dwError;
  BOOL            retVal = FALSE;
  TCHAR           szMsgBuffer[FTP_FUNCTIONS_BUFFER_SIZE];
  TCHAR           szFName[FTP_FUNCTIONS_BUFFER_SIZE];
  
  SendDlgItemMessage( hDlg, nListBoxId, LB_RESETCONTENT, 0, 0 );
  hFind = FtpFindFirstFile( hConnection, TEXT( "*.*" ), 
                            &dirInfo, dwFindFlags, 0 );
  if ( hFind == NULL )
  {
    dwError = GetLastError( );
    if( dwError == ERROR_NO_MORE_FILES )
    {
      StringCchCopy( szMsgBuffer, FTP_FUNCTIONS_BUFFER_SIZE,
        TEXT( "No files found at FTP location specified." ) );
      retVal = TRUE;
      goto DisplayDirError_1;
    }
    StringCchCopy( szMsgBuffer, FTP_FUNCTIONS_BUFFER_SIZE,
      TEXT( "FtpFindFirstFile failed." ) );
    goto DisplayDirError_1;
  }

  do
  {
    if( FAILED( StringCchCopy( szFName, FTP_FUNCTIONS_BUFFER_SIZE,
                  dirInfo.cFileName ) ) ||
        ( ( dirInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) &&
        ( FAILED( StringCchCat( szFName, FTP_FUNCTIONS_BUFFER_SIZE,
         TEXT( " <DIR> " ) ) ) ) ) )
    {
      StringCchCopy( szMsgBuffer, FTP_FUNCTIONS_BUFFER_SIZE,
        TEXT( "Failed to copy a file or directory name." ) );
      retVal = FALSE;
      goto DisplayDirError_2;
    }
    SendDlgItemMessage( hDlg, nListBoxId, LB_ADDSTRING, 
                        0, (LPARAM) szFName );
  } while( InternetFindNextFile( hFind, (LPVOID) &dirInfo ) );

  if( ( dwError = GetLastError( ) ) == ERROR_NO_MORE_FILES )
  {
    InternetCloseHandle(hFind);
    return( TRUE );
  }
  StringCchCopy( szMsgBuffer, FTP_FUNCTIONS_BUFFER_SIZE,
    TEXT( "FtpFindNextFile failed." ) );

DisplayDirError_2:
  InternetCloseHandle( hFind );
DisplayDirError_1:
  MessageBox( hDlg,
    (LPCTSTR) szMsgBuffer,
    TEXT( "DisplayFtpDir( ) Problem" ),
    MB_OK | MB_ICONERROR );
  return( retVal );
}

FtpGetCurrentDirectoryFtpSetCurrentDirectory 函数处理目录导航。

FtpGetCurrentDirectory 返回 FTP 服务器上的应用程序的当前目录。 包含 FTP 服务器上的根目录的目录路径。

FtpSetCurrentDirectory 更改服务器上的工作目录。 传递给 FtpSetCurrentDirectory 的目录信息可以是相对于当前目录的部分或完全限定的路径名称。 例如,如果应用程序当前位于目录“public/info”中,并且路径为“ftp/example”, 则 FtpSetCurrentDirectory 会将当前目录更改为“public/info/ftp/example”。

以下示例使用由 InternetConnect 返回的 FTP 会话句柄 hConnection。 新目录名称取自父对话框的编辑框,该对话框的 IDC 在 nDirNameId 参数中传递。 在进行目录更改之前,函数将检索当前目录并将其存储在同一编辑框中。 上面列出了末尾调用的 DisplayFtpDir 函数的 souce 代码。

BOOL WINAPI ChangeFtpDir( HWND hDlg, 
                          HINTERNET hConnection,
                          int nDirNameId, 
                          int nListBoxId )
{
  DWORD dwSize;
  TCHAR szNewDirName[FTP_FUNCTIONS_BUFFER_SIZE];
  TCHAR szOldDirName[FTP_FUNCTIONS_BUFFER_SIZE];
  TCHAR* szFailedFunctionName;

  dwSize = FTP_FUNCTIONS_BUFFER_SIZE;

  if( !GetDlgItemText( hDlg, nDirNameId, szNewDirName, dwSize ) )
  {
    szFailedFunctionName = TEXT( "GetDlgItemText" );
    goto ChangeFtpDirError;
  }

  if ( !FtpGetCurrentDirectory( hConnection, szOldDirName, &dwSize ))
  {
    szFailedFunctionName = TEXT( "FtpGetCurrentDirectory" );
    goto ChangeFtpDirError;
  }

  if( !SetDlgItemText( hDlg, nDirNameId, szOldDirName ) )
  {
    szFailedFunctionName = TEXT( "SetDlgItemText" );
    goto ChangeFtpDirError;
  }

  if( !FtpSetCurrentDirectory( hConnection, szNewDirName ) )
  {
    szFailedFunctionName = TEXT( "FtpSetCurrentDirectory" );
    goto ChangeFtpDirError;
  }
  return( DisplayFtpDir( hDlg, hConnection, 0, nListBoxId ) );

ChangeFtpDirError:
  InternetErrorOut( hDlg, GetLastError( ), szFailedFunctionName );
  DisplayFtpDir( hDlg, hConnection, INTERNET_FLAG_RELOAD, nListBoxId);
  return( FALSE );
}

在 FTP 服务器上操作目录

WinINet 提供在应用程序具有所需权限的 FTP 服务器上创建和删除目录的功能。 如果应用程序必须使用特定的用户名和密码登录到服务器,则创建 FTP 会话句柄时,可以在 InternetConnect 中使用这些值。

FtpCreateDirectory 函数采用有效的 FTP 会话句柄和 null 结尾的字符串,该字符串包含相对于当前目录的完全限定路径或名称,并在 FTP 服务器上创建一个目录。

以下示例显示了对 FtpCreateDirectory 的两次单独调用。 在这两个示例中,hFtpSession 是由 InternetConnect 函数创建的会话句柄,根目录是当前目录。

/* Creates the directory "test" in the current (root) directory. */
FtpCreateDirectory( hFtpSession, "test" );

/* Creates the directory "example" in the test directory. */
FtpCreateDirectory( hFtpSession, "\\test\\example" );

FtpRemoveDirectory 函数采用会话句柄和以 null 结尾的字符串,该字符串包含相对于当前目录的完全限定路径或名称,并从 FTP 服务器中删除该目录。

以下示例演示对 FtpRemoveDirectory 的两个示例调用。 在这两个调用中,hFtpSession 是由 InternetConnect 函数创建的会话句柄,根目录是当前目录。 根目录中有一个名为“test”的目录,“test”目录中有一个名为“example”的目录。

/* Removes the "example" directory (plus any files/directories it contains) from the "test" directory. */
FtpRemoveDirectory(hFtpSession,"\\test\\example");

/* Removes the "test" directory (plus any files/directories it contains) from the root directory. */
FtpRemoveDirectory(hFtpSession, "test");
FtpRemoveDirectory(hFtpSession,TEXT("\\test\\example"));
/* Removes the "example" directory and any files or 
directories contained in it from the "test" directory. */

FtpRemoveDirectory(hFtpSession, TEXT("test"));
/* Removes the "test" directory and any files or 
directories contained in it from the root directory. */

以下示例在 FTP 服务器上创建新目录。 新目录名称取自父对话框的编辑框,该对话框的 IDC 在 nDirNameId 参数中传递。 hConnection 句柄是在建立 FTP 会话后由 InternetConnect 创建的。 上面列出了末尾调用的 DisplayFtpDir 函数的源代码。

BOOL WINAPI CreateFtpDir( HWND hDlg, HINTERNET hConnection,
                          int nDirNameId, int nListBoxId )
{
  TCHAR szNewDirName[FTP_FUNCTIONS_BUFFER_SIZE];

  if( !GetDlgItemText( hDlg, nDirNameId, 
                       szNewDirName, 
                       FTP_FUNCTIONS_BUFFER_SIZE ) )
  {
    MessageBox( hDlg, 
                TEXT( "Error: Directory Name Must Be Specified" ),
                TEXT( "Create FTP Directory" ), 
                MB_OK | MB_ICONERROR );
    return( FALSE );
  }

  if( !FtpCreateDirectory( hConnection, szNewDirName ) )
  {
    InternetErrorOut( hDlg, GetLastError( ), 
                      TEXT( "FtpCreateDirectory" ) );
    return( FALSE );
  }

  return( DisplayFtpDir( hDlg, hConnection, 
                         INTERNET_FLAG_RELOAD, 
                         nListBoxId ) );
}

以下示例从 FTP 服务器中删除目录。 要删除的目录的名称从父对话框中的编辑框中获取,其 IDC 将传递到 nDirNameId 参数中。 hConnection 句柄是在建立 FTP 会话后由 InternetConnect 创建的。 上面列出了末尾调用的 DisplayFtpDir 函数的源代码。

BOOL WINAPI RemoveFtpDir( HWND hDlg, HINTERNET hConnection,
                          int nDirNameId, int nListBoxId )
{
  TCHAR szDelDirName[FTP_FUNCTIONS_BUFFER_SIZE];

  if( !GetDlgItemText( hDlg, nDirNameId, szDelDirName, 
                       FTP_FUNCTIONS_BUFFER_SIZE ) )
  {
    MessageBox( hDlg, 
                TEXT( "Error: Directory Name Must Be Specified" ),
                TEXT( "Remove FTP Directory" ), 
                MB_OK | MB_ICONERROR );
    return( FALSE );
  }

  if( !FtpRemoveDirectory( hConnection, szDelDirName ) )
  {
    InternetErrorOut( hDlg, GetLastError( ), 
                      TEXT( "FtpRemoveDirectory" ) );
    return( FALSE );
  }

  return( DisplayFtpDir( hDlg, hConnection, 
                         INTERNET_FLAG_RELOAD, nListBoxId ) );
}

在 FTP 服务器上获取文件

可通过三种方法从 FTP 服务器检索文件:

有关使用 InternetReadFile 函数的详细信息,请参阅 读取文件

如果文件的 URL 可用,应用程序可以调用 InternetOpenUrl 连接到该 URL,然后使用 InternetReadFile 控制文件的下载。 这样,应用程序就可以更严格地控制下载,非常适合不需要在 FTP 服务器上执行其他操作的情况。 有关如何直接访问资源的详细信息,请参阅 直接访问 URL

如果应用程序已使用 InternetConnect 与服务器建立 FTP 会话句柄,则应用程序可以使用现有文件名和本地存储文件的新名称调用 FtpOpenFile 。 然后,应用程序可以使用 InternetReadFile 下载文件。 这样,应用程序就可以更严格地控制下载内容,并保持与 FTP 服务器的连接,因此可以执行更多命令。

如果应用程序不需要严格控制下载,应用程序可以使用 FtpGetFile 和 FTP 会话句柄、远程文件名和本地文件名来检索文件。 FtpGetFile 执行与从 FTP 服务器读取文件并将其存储在本地相关的所有簿记和开销。

以下示例从 FTP 服务器检索文件并将其保存在本地。 FTP 服务器上的文件的名称取自父对话框中的编辑框,其 IDC 在 nFtpFileNameId 参数中传递,保存文件的本地名称取自 IDC 在 nLocalFileNameId 参数中传递的编辑框。 hConnection 句柄是在建立 FTP 会话后由 InternetConnect 创建的。

BOOL WINAPI GetFtpFile( HWND hDlg, HINTERNET hConnection,
                        int nFtpFileNameId, int nLocalFileNameId )
{
  TCHAR szFtpFileName[FTP_FUNCTIONS_BUFFER_SIZE];
  TCHAR szLocalFileName[FTP_FUNCTIONS_BUFFER_SIZE];
  DWORD dwTransferType;
  TCHAR szBoxTitle[] = TEXT( "Download FTP File" );
  TCHAR szAsciiQuery[] =
    TEXT("Do you want to download as ASCII text?(Default is binary)");
  TCHAR szAsciiDone[] = 
    TEXT( "ASCII Transfer completed successfully..." );
  TCHAR szBinaryDone[] = 
    TEXT( "Binary Transfer completed successfully..." );

  if( !GetDlgItemText( hDlg, nFtpFileNameId, szFtpFileName,
                       FTP_FUNCTIONS_BUFFER_SIZE ) ||
      !GetDlgItemText( hDlg, nLocalFileNameId, szLocalFileName,
                       FTP_FUNCTIONS_BUFFER_SIZE ) )
  {
    MessageBox( hDlg, 
                TEXT( "Target File or Destination File Missing" ),
                szBoxTitle, 
                MB_OK | MB_ICONERROR );
    return( FALSE );
  }

  dwTransferType = ( MessageBox( hDlg, 
                                 szAsciiQuery, 
                                 szBoxTitle, 
                                 MB_YESNO ) == IDYES ) ?
                   FTP_TRANSFER_TYPE_ASCII : FTP_TRANSFER_TYPE_BINARY;
  dwTransferType |= INTERNET_FLAG_RELOAD;

  if( !FtpGetFile( hConnection, szFtpFileName, szLocalFileName, FALSE,
                   FILE_ATTRIBUTE_NORMAL, dwTransferType, 0 ) )
  {
    InternetErrorOut( hDlg, GetLastError( ), TEXT( "FtpGetFile" ) );
    return( FALSE );
  }

  MessageBox( hDlg,( dwTransferType == 
                      (FTP_TRANSFER_TYPE_ASCII | INTERNET_FLAG_RELOAD)) ?
                      szAsciiDone : szBinaryDone, szBoxTitle, MB_OK );
  return( TRUE );
}

在 FTP 服务器上放置文件

在 FTP 服务器上放置文件有两种方法:

必须将数据发送到 FTP 服务器但不包含包含所有数据的本地文件的应用程序应使用 FtpOpenFile 在 ftp 服务器上创建和打开文件。 然后,应用程序可以使用 InternetWriteFile 将信息上传到文件。

如果文件已在本地存在,应用程序可以使用 FtpPutFile 将文件上传到 FTP 服务器。 FtpPutFile 执行将本地文件上传到远程 FTP 服务器的所有开销。

以下示例将本地文件复制到 FTP 服务器上。 文件的本地名称取自父对话框中的编辑框,其 IDC 在 nLocalFileNameId 参数中传递,文件保存在 FTP 服务器上的名称取自 IDC 在 nFtpFileNameId 参数中传递的编辑框。 hConnection 句柄是在建立 FTP 会话后由 InternetConnect 创建的。

BOOL WINAPI PutFtpFile( HWND hDlg, HINTERNET hConnection,
                        int nFtpFileNameId, int nLocalFileNameId )
{
  TCHAR szFtpFileName[FTP_FUNCTIONS_BUFFER_SIZE];
  TCHAR szLocalFileName[FTP_FUNCTIONS_BUFFER_SIZE];
  DWORD dwTransferType;
  TCHAR szBoxTitle[] = TEXT( "Upload FTP File" );
  TCHAR szASCIIQuery[] =
    TEXT("Do you want to upload as ASCII text? (Default is binary)");
  TCHAR szAsciiDone[] = 
    TEXT( "ASCII Transfer completed successfully..." );
  TCHAR szBinaryDone[] = 
    TEXT( "Binary Transfer completed successfully..." );

  if( !GetDlgItemText( hDlg, nFtpFileNameId, szFtpFileName,
                       FTP_FUNCTIONS_BUFFER_SIZE ) ||
      !GetDlgItemText( hDlg, nLocalFileNameId, szLocalFileName,
                       FTP_FUNCTIONS_BUFFER_SIZE ) )
  {
    MessageBox( hDlg, 
                TEXT("Target File or Destination File Missing"),
                szBoxTitle, 
                MB_OK | MB_ICONERROR );
    return( FALSE );
  }

  dwTransferType =
    ( MessageBox( hDlg, 
                  szASCIIQuery, 
                  szBoxTitle, 
                  MB_YESNO ) == IDYES ) ?
    FTP_TRANSFER_TYPE_ASCII : FTP_TRANSFER_TYPE_BINARY;

  if( !FtpPutFile( hConnection, 
                   szLocalFileName, 
                   szFtpFileName, 
                   dwTransferType, 
                   0 ) )
  {
    InternetErrorOut( hDlg, GetLastError( ), TEXT( "FtpGetFile" ) );
    return( FALSE );
  }

  MessageBox( hDlg,
              ( dwTransferType == FTP_TRANSFER_TYPE_ASCII ) ?
                szAsciiDone : szBinaryDone, szBoxTitle, MB_OK );
  return( TRUE );  // Remember to refresh directory listing
}

从 FTP 服务器中删除文件

若要从 FTP 服务器中删除文件,请使用 FtpDeleteFile 函数。 调用应用程序必须具有从 FTP 服务器中删除文件所需的权限。

以下示例从 FTP 服务器中删除文件。 要删除的文件的名称从父对话框中的编辑框中获取,其 IDC 在 nFtpFileNameId 参数中传递。 hConnection 句柄是在建立 FTP 会话后由 InternetConnect 创建的。 由于此函数不会刷新文件列表或目录显示,因此调用过程应在成功删除后执行此操作。

BOOL WINAPI DeleteFtpFile( HWND hDlg, HINTERNET hConnection,
                           int nFtpFileNameId )
{
  TCHAR szFtpFileName[FTP_FUNCTIONS_BUFFER_SIZE];
  TCHAR szBoxTitle[] = TEXT( "Delete FTP File" );

  if( !GetDlgItemText( hDlg, nFtpFileNameId, szFtpFileName,
                       FTP_FUNCTIONS_BUFFER_SIZE ) )
  {
    MessageBox( hDlg, TEXT( "File Name Must Be Specified!" ),
                szBoxTitle, MB_OK | MB_ICONERROR );
    return( FALSE );
  }

  if( !FtpDeleteFile( hConnection, szFtpFileName ) )
  {
    InternetErrorOut( hDlg, 
                      GetLastError( ), 
                      TEXT( "FtpDeleteFile" ) );
    return( FALSE );
  }

  MessageBox( hDlg, 
              TEXT( "File has been deleted" ), 
              szBoxTitle, 
              MB_OK );
  return( TRUE );  // Remember to refresh directory listing
}

重命名 FTP 服务器上的文件和目录

可以使用 FtpRenameFile 函数重命名 FTP 服务器上的文件和目录。 FtpRenameFile 接受两个 以 null 结尾的字符串,这些字符串包含相对于当前目录的部分或完全限定的名称。 函数将第一个字符串指定的文件的名称更改为第二个字符串指定的名称。

以下示例重命名 FTP 服务器上的文件或目录。 文件或目录的当前名称取自父对话框中的编辑框,其 IDC 在 nOldFileNameId 参数中传递,新名称取自 IDC 在 nNewFileNameId 参数中传递的编辑框。 hConnection 句柄是在建立 FTP 会话后由 InternetConnect 创建的。 由于此函数不会刷新文件列表或目录显示,因此调用进程应在成功重命名后执行此操作。

BOOL WINAPI RenameFtpFile( HWND hDlg, HINTERNET hConnection,
                           int nOldFileNameId, int nNewFileNameId )
{
  TCHAR szOldFileName[FTP_FUNCTIONS_BUFFER_SIZE];
  TCHAR szNewFileName[FTP_FUNCTIONS_BUFFER_SIZE];
  TCHAR szBoxTitle[] = TEXT( "Rename FTP File" );

  if( !GetDlgItemText( hDlg, nOldFileNameId, szOldFileName,
                       FTP_FUNCTIONS_BUFFER_SIZE ) ||
      !GetDlgItemText( hDlg, nNewFileNameId, szNewFileName,
                       FTP_FUNCTIONS_BUFFER_SIZE ) )
  {
    MessageBox( hDlg,
        TEXT( "Both the current and new file names must be supplied" ),
        szBoxTitle, 
        MB_OK | MB_ICONERROR );
    return( FALSE );
  }

  if( !FtpRenameFile( hConnection, szOldFileName, szNewFileName ) )
  {
    MessageBox( hDlg,
        TEXT( "FtpRenameFile failed" ),
        szBoxTitle, 
        MB_OK | MB_ICONERROR );
    return( FALSE );
  }
  return( TRUE );  // Remember to refresh directory listing
}

注意

WinINet 不支持服务器实现。 此外,不应从服务使用它。 对于服务器实现或服务,请使用 Microsoft Windows HTTP Services (WinHTTP)