2013-03-19 6 views
5

Ich habe Probleme, Dateien in einem FTP zu verwalten, wenn sie Sonderzeichen haben. Zum Beispiel Dateinamen mit ó oder ähnlichem.Sonderzeichen in FTP-Dateien

Ich gebe Ihnen ein Beispiel. Zuerst mag ich zur Liste und jede Datei von einem Ordner in dem FTP-Prozess:

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() 

Aber das mir Probleme geben, wenn die Datei Sonderzeichen enthält, da die Zeichenfolge ich für die Datei nicht „existiert“ auf das FTP, zum Beispiel:

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 

zum Beispiel kann die Datei EXAMPLE_aró auf dem FTP, hier als EXAMPLE_ar□ abgerufen wird, so dass, wenn ich versuche, um die Datei herunterzuladen es sagt, das tut existieren.

Wie kann ich damit umgehen?

Antwort

2

Geht man von den Antworten auf this question, können Sie die Codierung der StreamReader Sie verwenden angeben müssen, um zu bekommen die Dateiauflistung. Der Standardwert ist UTF-8, können Sie andere Codierungen verwenden wie so:

reader = New StreamReader(ftp.GetResponse().GetResponseStream(), System.Text.Encoding.Unicode) 

Wenn ich in Codierung Probleme laufen, ich kopiere in der Regel und die verstümmelte Zeichenfolge in einen Editor einfügen, die Hex-Werte für die Zeichen zeigen, und dann finde die Codierung von dort heraus.

Die Zeichenfolge, die Sie oben haben, enthält das Zeichen 00F3. Ihr Profil sagt, dass Sie in Spanien sind. diese beiden zusammen Einlochen, mit Hilfe von Google ich den FTP-Server bin zu raten, die spanische Geschmack von EBCDIC verwendet, die Codepage 1145. Diese So versuchen:

reader = New StreamReader(ftp.GetResponse().GetResponseStream(), System.Text.Encoding.GetEncoding(1145)) 

Edit: Es stellte sich heraus F3 ist die akute o In den meisten Codierungen, einschließlich erweitertem ASCII, kam die EBCDIC gerade bei meiner Suche auf.

+0

Hat nicht funktioniert. Anstatt eine Liste von Dateinamen zu haben, erhalte ich eine einzelne Zeichenfolge im Reader.ReadToEnd', das ich nicht teilen kann und alle Zeichen sind ungültig (alle unleserlichen Quadrate). Wenn sie in einem geeigneten Editor geöffnet sind, sind alle in Unicode chinesische Zeichen, und mit "1145" Codierung sind alle seltsame Zeichen wie "ÁÁ/ëÍ" – SysDragon

+0

Haben Sie versucht, ASCII? – Matt

+0

Welches 'ASCII' listet die Dateien auf, sondern setzt ein' '' wo die Sonderzeichen sein sollten. – SysDragon

0

Ich habe versucht, einige Sonderzeichen und die unten funktioniert gut für mich. Die listDir Funktion erstellt die Liste ... Vielleicht können Sie versuchen, und lassen Sie uns wissen ...

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

Ihr Code versucht und mir immer noch die unleserlich Zeichen. 'ListDirectoryDetails' funktioniert genauso wie' ListDirectory' zum Abrufen der Dateinamen. – SysDragon

0

In meinem Fall schien der Code mit akzentuierten lateinischen Zeichen gut zu funktionieren - es war nicht eine Codierung von lateinischen Zeichen so sehr wie das # Hash/Nummer-Symbol.

Die Antwort darauf kam von Gary Yang (Microsoft Online Community Support). Der Schlüssel war, Uri.EscapeDataString() zu verwenden. Seine Antwort hat nicht funktioniert, aber aus Respekt ist es unter:

Ich schlage vor, Sie versuchen, den Dateipfad zu verschlüsseln. Bitte beachten Sie den folgenden Code ein:

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); 

Hier ist meine Arbeitsversion:

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) 

... und für 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

Oh, auch ich habe festgestellt, ich habe ftpRequest.UseBinary = true; set so vielleicht, das bedeutet, ich muss String-Codierungen nicht angeben? – Colin