读取 FTP 个包含国际字符的文件
Read FTP file with international characters
我正在使用以下代码下载 FTP 位置文件。它适用于所有文件,文件名包含国际字符的文件除外。
我了解到 URI 格式不允许这样做,但如果在提到的位置有现有文件,如何下载。
为了测试,我在 IIS 下设置了本地 FTP 服务器,如下所示。
http://www.online-tech-tips.com/computer-tips/setup-ftp-server-in-windows-iis/
string mat_address = "ftp://localhost/";
StringBuilder result = new StringBuilder();
FtpWebRequest ftp = (FtpWebRequest)WebRequest.Create(mat_address);
ftp.Credentials = new NetworkCredential("userid", "Password");
ftp.Method = WebRequestMethods.Ftp.ListDirectory;
string[] downloadfile = null;
using (FtpWebResponse response = (FtpWebResponse)ftp.GetResponse())
using (StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.Default, true))
{
downloadfile = reader.ReadToEnd().Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
}
foreach (string d in downloadfile)
{
if (d.Contains("d"))
{
string temp = mat_address + HttpUtility.UrlPathEncode(d);
FtpWebRequest ftp2 = (FtpWebRequest)WebRequest.Create(temp);
ftp2.Credentials = new NetworkCredential("userid", "Password");
ftp2.Method = WebRequestMethods.Ftp.GetDateTimestamp;
ftp2.UseBinary = true;
ftp2.Proxy = null;
ftp2.KeepAlive = false;
ftp2.UsePassive = false;
FtpWebResponse response2 = ftp2.GetResponse() as FtpWebResponse;
DateTime temp1 = response2.LastModified.Date;
if (temp1 > DateTime.Now.AddDays(-10))
{
// Some extra work
}
}
}
我遇到错误
The remote server returned an error: (550) File unavailable (e.g., file not found, no access).
下面是我的 FTP 根文件夹,文件名有问题 diá.png
我使用 C# 进行编码,Visual Studio 2013 进行开发。有人能帮忙吗。
问题更新:
编码更改为 UTF8。
使用本地主机一切正常。但是当使用来自德国和瑞典等国际域的 FTP 服务器时。名称如下所示。
我收到以下行的错误。
FtpWebResponse response2 = ftp2.GetResponse() as FtpWebResponse;
文件名的十六进制值: Martin 建议包含。谢谢
31,30,31,33,36,2D,49,43,4F,4D,20,50,4A,C4,54,54,45,52,59,44,20,70,69,63,74,20,37,38,78,31,31,38,20,61,6E,6E,69,2D,76,65,72,73,61,72,69,75,73,20,5B,77,31,33,32,31,20,78,20,68,39,32,31,5D,20,6D,6D,20,44,49,46,46,55,53,45,2E,50,4E,47,
我会说,您必须转换接收到的文件名的编码以匹配本地文件系统的需要。你能 post 你查看的文件名是什么吗?我认为您得到了一个包含一些非法字符的转义字符串...
大多数 FTP 服务器应该使用 UTF-8 编码。您的本地 (IIS) 服务器也是如此。
所以你需要在解析目录列表时使用Encoding.UTF8
。
尽管您的 real/production 服务器似乎出现了某种故障。看起来它对目录列表使用 Windows-1252 编码。然而它声称(并且似乎要求)对命令进行 UTF-8 编码。这显然(理所当然地)混淆了 FileZilla。但我不明白,为什么它不能与 FtpWebRequest
一起使用,因为它应该使用 UTF-8(因为服务器积极响应 OPTS utf8 on
命令),并且您已尝试显式使用 Windows-1252编码,解析listing时。
无论如何,当你发现(在聊天中)WinSCP 工作时,你可以尝试使用 WinSCP .NET assembly。它还将使您的代码更简单:
SessionOptions sessionOptions = new SessionOptions();
sessionOptions.Protocol = Protocol.Ftp;
sessionOptions.HostName = "hostname";
sessionOptions.UserName = "username";
sessionOptions.Password = "password";
using (Session session = new Session())
{
session.Open(sessionOptions);
foreach (RemoteFileInfo fileInfo in session.ListDirectory("/textures").Files)
{
if (fileInfo.Name.Contains("d"))
{
if (fileInfo.LastWriteTime > DateTime.Now.AddDays(-10))
{
string sourcePath =
RemotePath.EscapeFileMask("/textures/" + fileInfo.Name);
session.GetFiles(sourcePath, @"c:\local\path\").Check();
}
}
}
}
或者,更简单,使用 file mask with time constraint:
SessionOptions sessionOptions = new SessionOptions();
sessionOptions.Protocol = Protocol.Ftp;
sessionOptions.HostName = "hostname";
sessionOptions.UserName = "username";
sessionOptions.Password = "password";
using (Session session = new Session())
{
session.Open(sessionOptions);
session.GetFiles("/textures/*d*>=10D", @"c:\local\path\").Check();
}
另请参阅 WinSCP 示例 How do I transfer new/modified files only?
我正在使用以下代码下载 FTP 位置文件。它适用于所有文件,文件名包含国际字符的文件除外。
我了解到 URI 格式不允许这样做,但如果在提到的位置有现有文件,如何下载。
为了测试,我在 IIS 下设置了本地 FTP 服务器,如下所示。
http://www.online-tech-tips.com/computer-tips/setup-ftp-server-in-windows-iis/
string mat_address = "ftp://localhost/";
StringBuilder result = new StringBuilder();
FtpWebRequest ftp = (FtpWebRequest)WebRequest.Create(mat_address);
ftp.Credentials = new NetworkCredential("userid", "Password");
ftp.Method = WebRequestMethods.Ftp.ListDirectory;
string[] downloadfile = null;
using (FtpWebResponse response = (FtpWebResponse)ftp.GetResponse())
using (StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.Default, true))
{
downloadfile = reader.ReadToEnd().Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
}
foreach (string d in downloadfile)
{
if (d.Contains("d"))
{
string temp = mat_address + HttpUtility.UrlPathEncode(d);
FtpWebRequest ftp2 = (FtpWebRequest)WebRequest.Create(temp);
ftp2.Credentials = new NetworkCredential("userid", "Password");
ftp2.Method = WebRequestMethods.Ftp.GetDateTimestamp;
ftp2.UseBinary = true;
ftp2.Proxy = null;
ftp2.KeepAlive = false;
ftp2.UsePassive = false;
FtpWebResponse response2 = ftp2.GetResponse() as FtpWebResponse;
DateTime temp1 = response2.LastModified.Date;
if (temp1 > DateTime.Now.AddDays(-10))
{
// Some extra work
}
}
}
我遇到错误
The remote server returned an error: (550) File unavailable (e.g., file not found, no access).
下面是我的 FTP 根文件夹,文件名有问题 diá.png
我使用 C# 进行编码,Visual Studio 2013 进行开发。有人能帮忙吗。
问题更新: 编码更改为 UTF8。 使用本地主机一切正常。但是当使用来自德国和瑞典等国际域的 FTP 服务器时。名称如下所示。
我收到以下行的错误。
FtpWebResponse response2 = ftp2.GetResponse() as FtpWebResponse;
文件名的十六进制值: Martin 建议包含。谢谢
31,30,31,33,36,2D,49,43,4F,4D,20,50,4A,C4,54,54,45,52,59,44,20,70,69,63,74,20,37,38,78,31,31,38,20,61,6E,6E,69,2D,76,65,72,73,61,72,69,75,73,20,5B,77,31,33,32,31,20,78,20,68,39,32,31,5D,20,6D,6D,20,44,49,46,46,55,53,45,2E,50,4E,47,
我会说,您必须转换接收到的文件名的编码以匹配本地文件系统的需要。你能 post 你查看的文件名是什么吗?我认为您得到了一个包含一些非法字符的转义字符串...
大多数 FTP 服务器应该使用 UTF-8 编码。您的本地 (IIS) 服务器也是如此。
所以你需要在解析目录列表时使用Encoding.UTF8
。
尽管您的 real/production 服务器似乎出现了某种故障。看起来它对目录列表使用 Windows-1252 编码。然而它声称(并且似乎要求)对命令进行 UTF-8 编码。这显然(理所当然地)混淆了 FileZilla。但我不明白,为什么它不能与 FtpWebRequest
一起使用,因为它应该使用 UTF-8(因为服务器积极响应 OPTS utf8 on
命令),并且您已尝试显式使用 Windows-1252编码,解析listing时。
无论如何,当你发现(在聊天中)WinSCP 工作时,你可以尝试使用 WinSCP .NET assembly。它还将使您的代码更简单:
SessionOptions sessionOptions = new SessionOptions();
sessionOptions.Protocol = Protocol.Ftp;
sessionOptions.HostName = "hostname";
sessionOptions.UserName = "username";
sessionOptions.Password = "password";
using (Session session = new Session())
{
session.Open(sessionOptions);
foreach (RemoteFileInfo fileInfo in session.ListDirectory("/textures").Files)
{
if (fileInfo.Name.Contains("d"))
{
if (fileInfo.LastWriteTime > DateTime.Now.AddDays(-10))
{
string sourcePath =
RemotePath.EscapeFileMask("/textures/" + fileInfo.Name);
session.GetFiles(sourcePath, @"c:\local\path\").Check();
}
}
}
}
或者,更简单,使用 file mask with time constraint:
SessionOptions sessionOptions = new SessionOptions();
sessionOptions.Protocol = Protocol.Ftp;
sessionOptions.HostName = "hostname";
sessionOptions.UserName = "username";
sessionOptions.Password = "password";
using (Session session = new Session())
{
session.Open(sessionOptions);
session.GetFiles("/textures/*d*>=10D", @"c:\local\path\").Check();
}
另请参阅 WinSCP 示例 How do I transfer new/modified files only?