2013-03-19 246 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