我在這裏寫了一個簡單的C#示例,也許有人會需要此代碼。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
namespace Deployer
{
public class RecursiveFolderUploader
{
private const string SrcFullPath = @"C:\prg\Snowinmars\Snowinmars.Ui";
private readonly IList<string> foldersOnServer;
private Client ftpClient; // that's your ftp client, init it
public RecursiveFolderUploader()
{
this.foldersOnServer = new List<string>();
}
private void UploadAll(DirectoryInfo directoryInfo)
{
// ftp://login:[email protected]/path/to/root/mydir/anotherdir/file.dat
// ^________________uri_______________________^_relevationPath_^
foreach (var file in directoryInfo.EnumerateFiles())
{
if (!file.Directory.FullName.StartsWith(RecursiveFolderUploader.SrcFullPath))
{
throw new InvalidOperationException($"File {file.FullName} is not from {RecursiveFolderUploader.SrcFullPath} folder");
}
string relevationPath; // all folders from root up to file
if (file.Directory.FullName.Length == RecursiveFolderUploader.SrcFullPath.Length)
{
relevationPath = "";
}
else
{
relevationPath = file.Directory.FullName.Substring(RecursiveFolderUploader.SrcFullPath.Length, file.Directory.FullName.Length - RecursiveFolderUploader.SrcFullPath.Length);
if (relevationPath.StartsWith("\\"))
{
relevationPath = relevationPath.Remove(0, 1);
}
}
string destination;
if (string.IsNullOrWhiteSpace(relevationPath))
{
destination = file.Name;
}
else
{
destination = Path.Combine(relevationPath, file.Name).Replace("\\", "/");
}
try
{
ftpClient.UploadFile(file.FullName, destination);
}
catch (WebException e)
{
// that means that there's no such folder or something else goes wrong
// we can check it by creating folders and try again
var parts = relevationPath.Replace("\\", "/").Split('/');
for (int i = 1; i <= parts.Length; i++)
{
var path = string.Join("/", parts.Take(i));
if (!foldersOnServer.Contains(path))
{
ftpClient.MakeDirectory(path);
foldersOnServer.Add(path);
}
}
try
{
ftpClient.UploadFile(file.FullName, destination);
}
catch (Exception innerE)
{
// if it doesn't help - trouble isn't in folders
throw new WebException($"Can't find folder {relevationPath}", innerE);
}
}
}
foreach (var directory in directoryInfo.EnumerateDirectories())
{
UploadAll(directory);
}
}
}
}
LIST和NLST可能會導致超時而不會導致立即失敗。只要目錄實際存在,它們就能正常工作。 – 2012-02-08 20:05:05
問題的一部分是我們正在接收來自客戶的FTP信息。我們不知道他們使用的FTP服務器。就我個人而言,我認爲我們正在解決錯誤的問題,並且一般來說需要考慮FTP的替代方案。但是,這是一個相當標準(如果不是很差)的方法來跨站點加載HTML頁面。像S3這樣的事情可能不是一種選擇。 – 2012-02-08 20:07:29
@TravisParks寫得不好的服務器會導致任何事情。命令本身不會導致任何事情。至於替代方案,請看看SFTP(SSH文件傳輸協議)。 – 2012-02-09 06:04:54