2013-03-19 131 views
5

我在使用特殊字符管理FTP中的文件时遇到问题。例如文件名与ó或类似。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□,所以当我尝试下载文件时,它说,这并不存在。

我该如何处理?

回答

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在我的搜索中刚刚出现。

+0

没有工作。我没有列出文件名,而是在'reader中获得一个字符串。ReadToEnd',我无法分割,所有的字符都是无效的(所有字符都是难以辨认的方块)。当在一个合适的编辑器中打开时,在unicode中,所有中文字符都是中文字符,并且“1145”编码都是奇怪的字符,如'ÃÊÈ/ëÍ'' – SysDragon 2013-04-02 08:25:22

+0

您是否尝试过ASCII? – Matt 2013-04-02 13:25:07

+0

哪个'ASCII'列出了文件,但在特殊字符应该放在哪里? – SysDragon 2013-04-02 13:55:21

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 
+0

想你的代码,仍然给了我难以辨认字符。 'ListDirectoryDe​​tails'与'ListDirectory'的作用相同,用于检索文件名。 – SysDragon 2013-04-02 08:34:03

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(); 
+0

哦,我也意识到我有 ftpRequest.UseBinary = true; 设置所以也许这意味着我不必指定字符串编码? – Colin 2016-01-19 22:22:00