5
4

3 回答 3

2

Judging from the answers to this question, you may need to specify the encoding of the StreamReader you're using to get the file listing. The default is UTF8, you can use other encodings like so:

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

When I run into encoding issues, I usually copy and paste the garbled string into an editor that can show the hex values for the characters, and then figure out the encoding from there.

The string you have above contains the character 00F3. Your profile says you are in Spain. Putting those two together, with the help of Google I am guessing the FTP server is using the Spanish flavor of EBCDIC, which is code page 1145. So try this:

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

Edit: Turns out F3 is the acute o in most encodings, including extended ASCII, the EBCDIC one just came up in my search.

于 2013-04-01T03:39:27.647 回答
0

I have tried using some special characters and the below works well for me. The listDir function creates the list... Maybe you can try and let us know...

 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
于 2013-03-28T01:10:16.250 回答
0

In my case, the code seemed to work fine with accented Latin characters - it wasn't an encoding of Latin characters so much as it was the # hash/number symbol.

The answer to that came from Gary Yang (Microsoft Online Community Support). The key was to use Uri.EscapeDataString(). His answer didn't work, but out of respect it is below:

I suggest you try to encode the file path. Please refer to the following code:

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

Here's my working version:

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)

... and for 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();
于 2016-01-19T05:04:36.350 回答