当我们有特殊字符时,我在FTP中管理文件时遇到问题。例如ó
或类似的文件名。
我举个例子。首先,我想列出并处理FTP中文件夹的每个文件:
ftp = CType(FtpWebRequest.Create(sFtpPath), FtpWebRequest)
ftp.Method = WebRequestMethods.Ftp.ListDirectory
reader = New StreamReader(ftp.GetResponse().GetResponseStream())
files = reader.ReadToEnd.Split(New String() {NewLine}, StringSplitOptions.RemoveEmptyEntries)
reader.Close()
但是当文件包含特殊字符时,这会给我带来问题,因为我对该文件的字符串不存在"存在"在FTP上,例如:
For Each sFich As String In files
ftp = CType(FtpWebRequest.Create(sFtpPath & "/" & sFich), FtpWebRequest)
ftp.Method = WebRequestMethods.Ftp.DownloadFile
reader = New StreamReader(ftp.GetResponse().GetResponseStream())
'...
Next
例如,FTP上的文件EXAMPLE_aró
,此处检索为EXAMPLE_ar□
,因此当我尝试下载文件时,它表示不存在。
我该如何处理?
答案 0 :(得分:2)
根据this question的答案判断,您可能需要指定用于获取文件列表的StreamReader
的编码。默认值为UTF8,您可以使用其他编码:
reader = New StreamReader(ftp.GetResponse().GetResponseStream(), System.Text.Encoding.Unicode)
当我遇到编码问题时,我通常会将乱码复制并粘贴到一个编辑器中,该编辑器可以显示字符的十六进制值,然后从中找出编码。
上面的字符串包含字符00F3。您的个人资料显示您在西班牙。把这两个放在一起,在谷歌的帮助下我猜测FTP服务器正在使用西班牙语的EBCDIC,这是代码页1145.所以试试这个:
reader = New StreamReader(ftp.GetResponse().GetResponseStream(), System.Text.Encoding.GetEncoding(1145))
编辑:结果F3是大多数编码中的急性编码,包括扩展的ASCII,我的搜索中出现了EBCDIC。
答案 1 :(得分:0)
我尝试过使用一些特殊字符,下面的效果很适合我。 listDir函数创建列表......也许你可以尝试告诉我们......
Public Shared Function DownloadFileFromServer(fileUri As Uri) As Boolean
If fileUri.Scheme <> Uri.UriSchemeFtp Then
Return False
End If
' Get the object used to communicate with the server.
Dim request As New WebClient()
request.Credentials = New NetworkCredential("user", "pass")
Try
Dim newFileData As Byte() = request.DownloadData(fileUri.ToString())
Dim fileString As String = System.Text.Encoding.UTF8.GetString(newFileData)
'do something with data
Console.WriteLine(fileString)
Catch e As WebException
Console.WriteLine(e.ToString())
End Try
Return True
End Function
Public Shared Function listDir() As Boolean
Dim request As FtpWebRequest = DirectCast(WebRequest.Create("ftp://www.yourftpsite.com/docs/"), FtpWebRequest)
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails
request.Credentials = New NetworkCredential("user", "pass")
Dim response As FtpWebResponse = DirectCast(request.GetResponse(), FtpWebResponse)
Dim responseStream As Stream = response.GetResponseStream()
Dim reader As New StreamReader(responseStream)
Dim dirlist As String() = Nothing
dirlist = reader.ReadToEnd().Split(New String() {vbCr & vbLf}, StringSplitOptions.RemoveEmptyEntries)
For Each dirLine As String In dirlist
Dim dirData As String = dirLine
' Parse date
Dim lineDate As String = dirData.Substring(0, 17)
Dim dateTime__1 As DateTime = DateTime.Parse(lineDate)
dirData = dirData.Remove(0, 24)
' check if line is a directory
Dim dir As String = dirData.Substring(0, 5)
Dim isDirectory As Boolean = dir.Equals("<dir>", StringComparison.InvariantCultureIgnoreCase)
dirData = dirData.Remove(0, 5)
dirData = dirData.Remove(0, 10)
' get the filename
If Not isDirectory Then
Dim fileName As String = dirData
'the actual filename
Console.WriteLine("name= " & fileName)
End If
Next
reader.Close()
response.Close()
Return True
End Function
答案 2 :(得分:0)
在我的情况下,代码似乎与重音拉丁字符一起使用 - 它不是拉丁字符的编码,而是#hash / number符号。
答案来自Gary Yang (Microsoft Online Community Support)。关键是使用Uri.EscapeDataString()。他的回答不起作用,但出于尊重,它在下面:
我建议你尝试编码文件路径。请参考以下代码:
string FTPFilePath = "ftp://myserverip.com/Beatles #1 Hits/Help document.mp3";
if ((FTPFilePath).IndexOf("#") > -1){
targetUri = new Uri(Uri.EscapeDataString(FTPFilePath));
}
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(targetUri);
这是我的工作版本:
Dim ftpFilePath = "ftp://myserverip.com/Beatles #1 Hits/Help document.mp3"
Dim parsedUri = new Uri(ftpFilePath)
Dim scheme = parsedUri.Scheme
Dim host = parsedUri.Host
Dim port = parsedUri.Port
Dim pathThatMightHaveHashSigns = ftpFilePath.Replace(String.Format("{0}://{1}", scheme, host), String.Empty)
'Dim targetUri = new Uri(Uri.EscapeDataString(ftpFilePath))
' The above line would throw a UriFormatException "Invalid URI: The format of the URI could not be determined."
Dim targetUri = new UriBuilder(scheme, host, port, pathThatMightHaveHashSigns).Uri
Dim request = CType(WebRequest.Create(targetUri), FtpWebRequest)
...和C#:
var ftpFilePath = "ftp://myserverip.com/Beatles #1 Hits/Help document.mp3";
var parsedUri = new Uri(ftpFilePath);
var scheme = parsedUri.Scheme;
var host = parsedUri.Host;
var port = parsedUri.Port;
var pathThatMightHaveHashSigns = ftpFilePath.Replace(String.Format("{0}://{1}", scheme, host), String.Empty);
//var targetUri = new Uri(Uri.EscapeDataString(ftpFilePath));
// The above line would throw a UriFormatException "Invalid URI: The format of the URI could not be determined."
var targetUri = new UriBuilder(scheme, host, port, pathThatMightHaveHashSigns).Uri;
targetUri.Dump();