100分求一递归源码:将远程ftp主机目录A中的所有文件及目录移动到B目录中

wangrumeng 2009-03-24 11:06:33
环境:asp.net1.1,c#

现有一ftp操作类,源码如下。请使用这个类中提供的各种方法来实现:

ftp服务器上有两个目录A和B,要求把A目录内的所有东西(包含文件和子目录)都移动到B目录中。

ftp操作源码太长贴不出来,请见:http://www.cnblogs.com/wskfire/archive/2007/11/30/978171.html

注:原来ftp操作中 文件重命名和文件移动 是同一个命令!
...全文
757 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
ichinaec 2009-04-30
  • 打赏
  • 举报
回复
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下载数据的时间!整了半天不让我发说我刷楼,我换个帐号上!咬你!
szpublice 2009-04-29
  • 打赏
  • 举报
回复
TreeView是用来存树结构的。如果不用这个你也可以用别的来存,比如Datatable,只不过会麻烦些!而且从数据上来看不容易理解。

你可以在你的Form里放个treeView控件,然后用上面的函数稍为修改,就可以测试获得的目录结构是否正确了。
szpublice 2009-04-29
  • 打赏
  • 举报
回复
引用:而实际上,这个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树,

后面如何处理这个树,就是你自已的做法了。
szpublice 2009-04-29
  • 打赏
  • 举报
回复
我说一下,你可能需要自已写,因为我现在没有那么多的时间慢慢写。我找不到你上面说的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
ichinaec 2009-04-29
  • 打赏
  • 举报
回复
a
路人乙e 2009-03-24
  • 打赏
  • 举报
回复
要是代码移动的话,两句话就行了

System.IO.Directory.Delete("c:/b");//删除目标目录
System.IO.Directory.Move("c:/a","c:/b");//移动文件到目标目录
duping9626 2009-03-24
  • 打赏
  • 举报
回复
直接RenameRemoteFile("aa","bb/aa")
路人乙e 2009-03-24
  • 打赏
  • 举报
回复
似乎不太明白
既然是ftp目录,直接使用ftp根据移动位置不行吗
wangrumeng 2009-03-24
  • 打赏
  • 举报
回复
谢谢楼上,但我没怎么明白你的意思。我要做的是ftp服务器上目录的移动,而不是先把目录下载下来然后再传上去,这样太影响效率了。还有就是FtpWebResponse貌似是.net2.0的吧,我现在是.net1.1
Jcomet 2009-03-24
  • 打赏
  • 举报
回复
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");

}
wangrumeng 2009-03-24
  • 打赏
  • 举报
回复
大家都哪去了 顶一个
duping9626 2009-03-24
  • 打赏
  • 举报
回复
RenameRemoteFile("aa","bb/aa")
可以移动整个目录,不只是文件,aa目录移至bb(bb要存在,不存在创建)下
wangrumeng 2009-03-24
  • 打赏
  • 举报
回复
要实现ftp目录移动,需要用ftp指令。我也已经找到了一个用ftp指令操作文件的类:http://www.cnblogs.com/wskfire/archive/2007/11/30/978171.html

上面的这个类就可以实现文件的移动,也就是ftp重命名指令和移动指令是一样的。所以用RenameRemoteFile("aa.txt","bb/aa.txt")来移动一个文件。

现在求移动一个目录的递归代码。谢谢各位啦
wangrumeng 2009-03-24
  • 打赏
  • 举报
回复
to phoebuswei:

不是你说的意思。Directory是操作web服务器上磁盘目录的方法。

我要的是,通过web服务器server1上的一个页面如a.aspx上的一个按钮,实现将另一台ftp远程服务器server2的目录A移动到目录B。
当然前提是server2已经向server1开发了相应的serv-U权限。这个前提的满足的。

现在就求一个c#的移动此server2上目录的递归代码。
wangrumeng 2009-03-24
  • 打赏
  • 举报
回复
phoebuswei 2009-03-24
  • 打赏
  • 举报
回复
您是不是要这样啊

string[] strDirs = Directory.GetDirectories("c:\....");
//然后循环.
wangrumeng 2009-03-24
  • 打赏
  • 举报
回复
哭啦~~~~~~~~~~都没有人理我~~~~~~~~~~~~~~~
wangrumeng 2009-03-24
  • 打赏
  • 举报
回复
楼上说的 是啥子意思啦
fgh0302 2009-03-24
  • 打赏
  • 举报
回复
m目录上面不是很有 更大的容器吗,直接移动丫的·
wangrumeng 2009-03-24
  • 打赏
  • 举报
回复
怎么都没有人来看看啊,大家都去哪里了,帮帮忙啦
加载更多回复(5)

62,271

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧