环境:asp.net1.1,c#现有一ftp操作类,源码如下。请使用这个类中提供的各种方法来实现:ftp服务器上有两个目录A和B,要求把A目录内的所有东西(包含文件和子目录)都移动到B目录中。ftp操作源码太长贴不出来,请见:http://www.cnblogs.com/wskfire/archive/2007/11/30/978171.html注:原来ftp操作中 文件重命名和文件移动 是同一个命令!

解决方案 »

  1.   

    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using System.Net;
    using System.IO;
    using System.Text;public class FtpUpDown
    {
        string ftpServerIPout;
        string ftpServerIPin;
        string ftpUserIDout;
        string ftpUserIDin;
        string ftpPasswordout;
        string ftpPasswordin;
        FtpWebRequest reqFTPout;
        FtpWebRequest reqFTPin;   public FtpUpDown(string ftpServerIPout, string ftpUserIDout,string ftpPasswordout,string ftpServerIPin, string ftpUserIDin ,string ftpPasswordin)
       {        this.ftpServerIPout = ftpServerIPout;
            this.ftpServerIPin=ftpServerIPin;
            this.ftpUserIDout = ftpUserIDout;
            this.ftpUserIDin = ftpUserIDin;
            this.ftpPasswordout = ftpPasswordout;
            this.ftpPasswordin = ftpPasswordin;    }
        private void Connect(string pathout, string pathin)//连接ftp
        {
            // 根据uri创建FtpWebRequest对象
            reqFTPout = (FtpWebRequest)FtpWebRequest.Create(new Uri(pathout));
            // 指定数据传输类型
            reqFTPout.UseBinary = true;
            // ftp用户名和密码
            reqFTPout.Credentials = new NetworkCredential(ftpUserIDout, ftpPasswordout);
            reqFTPout.Method=WebRequestMethods.Ftp.DownloadFile;
            // 根据uri创建FtpWebRequest对象
            reqFTPin = (FtpWebRequest)FtpWebRequest.Create(new Uri(pathin));
            // 指定数据传输类型
            reqFTPin.UseBinary = true;
            // ftp用户名和密码
            reqFTPin.Credentials = new NetworkCredential(ftpUserIDin, ftpPasswordin);
            reqFTPin.Method = WebRequestMethods.Ftp.UploadFile;
        }
       public bool Download(string fileName)/**/////上面的代码实现了从ftp服务器下载文件的功能
       {
           try
           {
                string urlout = "ftp://" + ftpServerIPout + "/" + fileName;
                string urlin = "ftp://" + ftpServerIPin + "/" + fileName;
                Connect(urlout, urlin);//连接 
                FtpWebResponse response = (FtpWebResponse)reqFTPout.GetResponse();
                Stream ftpStream = response.GetResponseStream();
                long cl = response.ContentLength;
                int bufferSize = 2048;
                int readCount;
                byte[] buffer = new byte[bufferSize];
                readCount = ftpStream.Read(buffer, 0, bufferSize);
                Stream strm = reqFTPin.GetRequestStream();
                while (readCount != 0)
                {
                    strm.Write(buffer, 0, bufferSize);
                    readCount = ftpStream.Read(buffer, 0, bufferSize);
                }
                ftpStream.Close();
                strm.Close();
                response.Close();
                return true;
           }
           catch 
           {
                return false;       }
        }
          
        }后台调用:protected void Button1_Click(object sender, EventArgs e)
        {
              FtpUpDown ftpUpDown = new FtpUpDown("192.168.0.26", "tfds", "tfds","192.168.0.34","tfds","tfds");
              ftpUpDown.Download("2.txt");
              Response.Write("success");    }
      

  2.   

    谢谢楼上,但我没怎么明白你的意思。我要做的是ftp服务器上目录的移动,而不是先把目录下载下来然后再传上去,这样太影响效率了。还有就是FtpWebResponse貌似是.net2.0的吧,我现在是.net1.1
      

  3.   

    似乎不太明白
    既然是ftp目录,直接使用ftp根据移动位置不行吗
      

  4.   

    要是代码移动的话,两句话就行了System.IO.Directory.Delete("c:/b");//删除目标目录
    System.IO.Directory.Move("c:/a","c:/b");//移动文件到目标目录
      

  5.   

    duping9626 
    风花雪月:RenameRemoteFile("aa","bb/aa")的思路是正确的,我要做的就是这样的操作。但这是移动一个文件,所以我现在需要大家帮忙,帮我写一个递归,移动整个目录。谢谢
      

  6.   

    路人乙  —挣钱,买房,取老婆:你说的是操作web服务器上文件目录的方法,不是我要做的。我现在要的是,通过web服务器操作另一台ftp服务器上才磁盘目录。谢谢。
      

  7.   

    是的,直接调用源码的方法RenameRemoteFile("aa","bb/aa")就可以做到了
    移动也是重命名
      

  8.   

    风花雪月:你好,RenameRemoteFile("aa","bb/aa")是可以做文件移动的。我现在要移动的不是一个文件,而是一个目录,所以要递归遍历整个目录,对其下的所有文件进行移动。所以本贴的主题是,求个递归遍历。谢谢大家。
      

  9.   

    您是不是要这样啊 string[] strDirs = Directory.GetDirectories("c:\....");
    //然后循环.
      

  10.   

    to phoebuswei:不是你说的意思。Directory是操作web服务器上磁盘目录的方法。我要的是,通过web服务器server1上的一个页面如a.aspx上的一个按钮,实现将另一台ftp远程服务器server2的目录A移动到目录B。
    当然前提是server2已经向server1开发了相应的serv-U权限。这个前提的满足的。现在就求一个c#的移动此server2上目录的递归代码。
      

  11.   

    要实现ftp目录移动,需要用ftp指令。我也已经找到了一个用ftp指令操作文件的类:http://www.cnblogs.com/wskfire/archive/2007/11/30/978171.html 上面的这个类就可以实现文件的移动,也就是ftp重命名指令和移动指令是一样的。所以用RenameRemoteFile("aa.txt","bb/aa.txt")来移动一个文件。现在求移动一个目录的递归代码。谢谢各位啦
      

  12.   

    RenameRemoteFile("aa","bb/aa")
    可以移动整个目录,不只是文件,aa目录移至bb(bb要存在,不存在创建)下
      

  13.   

    我说一下,你可能需要自已写,因为我现在没有那么多的时间慢慢写。我找不到你上面说的vb.net版的方法,而且我要用ftpWebRequest这个类来操作,不要用你上面那个,我说说想法,一定可行!
    '建议用TreeView来保存你的目录遍历,文件不需要遍历,先生成目录结构,类似命令行的Tree命令,先遍历目录,然后在你的A目录下从Tree的顶级往下建目录及子目录,然后在建每个目录的时候,检查当前目录下是不是有文件,如果有把文件复制或移动过去!    Private Sub loadTree(ByVal Nodes As TreeNodeCollection, ByVal lbID As Integer)
            'TreeView1.Nodes.Clear()
            'TreeView1.Nodes.Add("Hello")
            'TreeView1.Nodes.Add("Hello111")
            'TreeView1.Nodes(0).Nodes.Add("test")
            'TreeView1.Nodes(1).Nodes.Add("test")
            '获得各级分类
            Dim sNode As Integer = -1
            Dim CmdText As String = "Select * From sys_lb where FolderID=" + lbID.ToString + " Order by ID"
            Dim Ds As DataSet = New DataSet
            Ds = SqlDB.Fill(CmdText, SqlConn)
            If IsNothing(Ds) = True Then
                SqlDB.WriteDBError(SqlDB.Ex)
                Exit Sub
            End If
            If Ds.Tables(0).Rows.Count > 0 Then
                '加载节点
                Dim I As Integer
                For I = 0 To Ds.Tables(0).Rows.Count - 1
                    sNode += 1
                    Dim mylbName As String = Ds.Tables(0).Rows(I).Item("lbName").ToString
                    Dim mylbID As String = Ds.Tables(0).Rows(I).Item("ID").ToString
                    Nodes.Add(mylbID, mylbName)
                    '读取当前节点的子节点加载
                    loadTree(Nodes(sNode).Nodes, CInt(mylbID))
                Next
            End If
            TreeView1.ExpandAll()
        End Sub这个函数给您参考研究一下,许多年前我写的一套进销存系统里面的分类管理,它实现了对产品分类的无限级分类的遍历。也适合你的需求,用TreeView来保存你的目录结构。第一个参数,是子节点,第二个参数是ID,而实际上,这个ID,你可以把它视为一个当前目录的路径。
    列如这样的目录结构:
    E:.
    ├─adapter
    ├─core
    ├─data
    ├─dd
    ├─legacy
    │  └─layout
    ├─locale
    ├─state
    ├─util
    ├─widgets
    │  ├─form
    │  ├─grid
    │  ├─layout
    │  ├─menu
    │  ├─tips
    │  └─tree
    └─yui
    假设E:是根目录,则首次遍历的时候,传入E,第二次遍历的时候,分别传入的参数是通过循环把E:\下面的二级目录都调用一次这个函数,它会自动装载到TreeView的结构里。_______________________________________________________________________________如有问题欢迎沟通QQ:435045
      

  14.   

    引用:而实际上,这个ID,你可以把它视为一个当前目录的路径。 函数里的SQL查询,你换成你对当前目录的FTP列表命令取得当前这个目录下的所有目录,然后,进入下面的:        If Ds.Tables(0).Rows.Count > 0 Then 
                '加载节点 
                Dim I As Integer 
                For I = 0 To Ds.Tables(0).Rows.Count - 1 
                    sNode += 1 
                    Dim mylbName As String = Ds.Tables(0).Rows(I).Item("lbName").ToString 
                    Dim mylbID As String = Ds.Tables(0).Rows(I).Item("ID").ToString 
                    Nodes.Add(mylbID, mylbName) 
                    '读取当前节点的子节点加载 
                    loadTree(Nodes(sNode).Nodes, CInt(mylbID)) 
                Next 
            End If 这个你可以认为是判断当前目录下面是不是有子目录,如果有的话,循环调用获得当前目录下所有目录的子目录。这样的遍历只要当前目录下还有子目录,它就会一直遍历下去,不断调用自身,直到没有目录为止。这样就得到了一个目录的TreeView树,后面如何处理这个树,就是你自已的做法了。
      

  15.   

    TreeView是用来存树结构的。如果不用这个你也可以用别的来存,比如Datatable,只不过会麻烦些!而且从数据上来看不容易理解。你可以在你的Form里放个treeView控件,然后用上面的函数稍为修改,就可以测试获得的目录结构是否正确了。
      

  16.   

    Public Class Form1    Dim ftp As ftpClient '这是为了方便操作自已写的一个类,用ftpWebRequest来FTP的。    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            '同样是自已写的一个类,用来保存FTP帐号信息
            Dim Dec As New ftpClient.FtpDetails("125.***.***.***", 21, "username", "ftpPassword")
            ftp = New ftpClient(Dec) '创建对象实例。你可以用你自已的FTP方法来实现。
            loadTree(TreeView1.Nodes, "")
        End Sub    Private Sub loadTree(ByVal Nodes As TreeNodeCollection, ByVal Path As String)
            '获得各级分类
            Dim sNode As Integer = -1
            '通过FTP获得当前目录列表
            Dim result As String = ftp.GetFileList(Path)
            Dim files() As String = Split(result, vbCrLf) '把FTP服务器返回的文本,分离出是目录还是文件,文件或目录名,文件大小
            Dim ffi As New ftpClient.FtpListFileInfo
            If files.Length > 0 Then
                '加载节点
                Dim I As Integer
                For I = 0 To files.Length - 2
                    Dim mylbName As String = files(I).ToString
                    ffi.ParserString(files(I)) '对返回的单行做分割。分离出是目录还是文件,文件或目录名,文件大小
                    If ffi.IsDirectory = True And ffi.FileName <> ".." And ffi.FileName <> "." Then '如果是有效的目录。
                        sNode += 1
                        Nodes.Add(0, ffi.FileName) '由于是目录,前面的参数保存了类似.Tag一样的作用,这里保存了文件的size
                        Dim newpath As String = Path + "/" + ffi.FileName 'FileName如果是文件表示文件名,否则表示目录名
                        Application.DoEvents()
                        '读取当前节点的子节点加载()
                        loadTree(Nodes(sNode).Nodes, newpath) '递归检查当前目录下是否有子目录
                    ElseIf ffi.IsDirectory = False Then '如果是文件
                        sNode += 1
                        Nodes.Add(ffi.FileSize.ToString, ffi.FileName) '加入到节点中
                    End If
                Next
            End If
            TreeView1.ExpandAll()
        End Sub    Private Sub TreeView1_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterSelect
            Label1.Text = "当前选中节点的完整路径是:" + e.Node.FullPath.ToString + "  文件大小:" + e.Node.Name.ToString
        End Sub
    End Class根据目录级数及连接速度决定生成的速度。主要消耗时间的代码在于连接FTP下载数据的时间!整了半天不让我发说我刷楼,我换个帐号上!咬你!