FTP文件中的特殊字符

时间:2013-03-19 12:35:28

标签: vb.net ftp special-characters ftpwebrequest

当我们有特殊字符时,我在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□,因此当我尝试下载文件时,它表示不存在。

我该如何处理?

3 个答案:

答案 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();