C# FTP客户端-FTP服务器中的文件/文件夹列表无效

C# FTP客户端-FTP服务器中的文件/文件夹列表无效,c#,ftp,C#,Ftp,我正在用C#开发自己的FTP客户机,奇怪的是,有时(开始比以前更频繁)我会从FTP服务器收到无效(损坏)的文件/文件夹列表,看起来是这样的: drwxr--r-- 1 user group 0 Jul 10 08:53 .\r drwxr--r-- 1 user group 0 Jun 19 10:47 NetBeansProjects\r drwxr--r-- 1 user group 0 May 28

我正在用C#开发自己的FTP客户机,奇怪的是,有时(开始比以前更频繁)我会从FTP服务器收到无效(损坏)的文件/文件夹列表,看起来是这样的:

drwxr--r--   1 user     group          0 Jul 10 08:53 .\r
drwxr--r--   1 user     group          0 Jun 19 10:47 NetBeansProjects\r
drwxr--r--   1 user     group          0 May 28 22:07 NFS Most Wanted\r
0 May 28 18:57 My Skype Content\r
drwxr--r--   1 user     group      drwxr-
奇怪的是,有时上面的列表是正确的:

drwxr--r--   1 user     group          0 Jul 10 08:53 .\r
drwxr--r--   1 user     group          0 Jun 19 10:47 NetBeansProjects\r
drwxr--r--   1 user     group          0 May 28 22:07 NFS Most Wanted\r
drwxr--r--   1 user     group          0 May 28 18:57 My Skype Content\r
从FTP服务器接收文件/文件夹列表的方法是: (我还附加了与该方法getRemoteFolders()连接的其他方法)

public void getRemoteFolders()
{
字符串文件或文件夹;
字符串folderList=“”;
folderList=Encoding.ASCII.GetString(SendPassiveFTCmd(“LIST\r\n”));
filesAndFolders=folderList.Split(“\n”.ToCharArray());
[…]//代码的其余部分,不重要
}
公共字节[]sendPassiveFTCmd(字符串cmd)
{
字节[]数据;
System.Collections.ArrayList al=新的ArrayList();
byte[]RecvBytes=新字节[byte.MaxValue];
Int32字节;
Int32总长度=0;
szData=System.Text.Encoding.ASCII.GetBytes(cmd.tocharray());
网络流被动连接;
被动连接=createPassiveConnection();
tbStatus.Text+=“\r\n输入:”+cmd;
StreamReader commandStream=新的StreamReader(NetStrm);
NetStrm.Write(szData,0,szData.Length);
while(true)
{
字节=被动连接.Read(RecvBytes,0,RecvBytes.Length);

如果(bytes很好,那么首先,您主要忽略了
Read
返回的值—您调用的是
al.AddRange(RecvBytes)
,就好像它充满了有效数据—可能不是这样

不过,从流中读取字节数组有一种更简单的方法-使用
MemoryStream
。例如:

public static byte[] ReadFully(Stream input)
{
    byte[] buffer = new byte[16*1024];
    using (MemoryStream ms = new MemoryStream())
    {
        int read;
        while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
        {
            ms.Write(buffer, 0, read);
        }
        return ms.ToArray();
    }
}
(顺便问一下,你在使用.NET1.1吗?如果是的话,避免使用非泛型集合是值得的…)

我注意到您也没有关闭流-这是个坏主意。请使用
using
语句关闭流,如下所示(名称也更改为更为.NET惯用):


还要注意的是,您每次都从NetStrm创建一个新的StreamReader。这可能是个坏主意-我将创建一个StreamReader和一个StreamWriter来包装NetStrm,然后您根本不需要处理二进制数据。否则,新的StreamReader可能会读取比您要求的行更多的数据,导致您下次将丢失数据。

首先,您主要忽略了
读取所返回的值-您正在调用
al.AddRange(RecvBytes)
,就好像它充满了有效数据-可能不是这样

不过,从流中读取字节数组有一种更简单的方法-使用
MemoryStream
。例如:

public static byte[] ReadFully(Stream input)
{
    byte[] buffer = new byte[16*1024];
    using (MemoryStream ms = new MemoryStream())
    {
        int read;
        while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
        {
            ms.Write(buffer, 0, read);
        }
        return ms.ToArray();
    }
}
(顺便问一下,你在使用.NET1.1吗?如果是的话,避免使用非泛型集合是值得的…)

我注意到您也没有关闭流-这是个坏主意。请使用
using
语句关闭流,如下所示(名称也更改为更为.NET惯用):

还要注意的是,您每次都从NetStrm创建一个新的StreamReader。这可能是个坏主意-我将创建一个StreamReader和一个StreamWriter来包装NetStrm,然后您根本不需要处理二进制数据。否则,新的StreamReader可能会读取比您要求的行更多的数据,导致您下次将丢失数据

public byte[] SendPassiveFTPcmd(string cmd)
{
    using (Stream passiveConnection = CreatePassiveConnections())
    {
        byte[] commandData = Encoding.ASCII.GetBytes(cmd);
        NetStrm.Write(commandData, 0, commandData.Length);
        tbStatus.Text += "\r\nSent:" + cmd;

        byte[] data = ReadFully(passiveConnection);

        StreamReader commandStream = new StreamReader(NetStrm);
        tbStatus.Text += "\r\nRcvd:" + commandStream.ReadLine(); // 125
        tbStatus.Text += "\r\nRcvd:" + commandStream.ReadLine(); // 226
        return data;
    }
}