Board logo

标题: [文件操作] [已解决]批处理文件复制操作--谢谢朋友们无私帮助! [打印本页]

作者: 3Q3Q    时间: 2009-12-7 17:05     标题: [已解决]批处理文件复制操作--谢谢朋友们无私帮助!

用COPY 命令从X1文件夹每隔一分钟向X2文件夹复制文件,X1文件夹不停的有新文件传入,请问怎么才可以防止X1已经复制到X2的文件再次被执行复制操作?只写出判断部分就好。3Q3Q

[ 本帖最后由 3Q3Q 于 2009-12-9 16:38 编辑 ]
作者: pumahxh    时间: 2009-12-7 23:08

光写判断部分恐怕不一定行,我用这个方法,经测试合格,如果文件名含空格,则必须将代码再处理下,我想你自己应该会吧。假设两个文件夹都在C:\下。
  1. @echo off
  2. cd/d c:\X2
  3. :loop
  4. for /r c:\X2 %%i in (*.*) do  if not exist c:\X1\%%~nxi copy %%~nxi c:\X1
  5. ping -n 61 127.1>nul
  6. goto loop
复制代码

作者: Batcher    时间: 2009-12-7 23:44     标题: 回复 2楼 的帖子

给路径加上双引号不就可以兼容空格了?
作者: pumahxh    时间: 2009-12-7 23:49     标题: 回复3楼

开始也是这么想的,还有一种方法
如果将copy %%~nxi c:\X1中改成copy %%~si c:\X1好像也不错,而且还可以删去cd/d c:\X2,简化了些代码
  1. @echo off
  2. :loop
  3. for /r c:\X2 %%i in (*.*) do  if not exist c:\X1\%%~nxi copy %%~si c:\X1
  4. ping -n 61 127.1>nul
  5. goto loop
复制代码

[ 本帖最后由 pumahxh 于 2009-12-7 23:56 编辑 ]
作者: netbenton    时间: 2009-12-8 07:27

xcopy 有自动文件更新复制功能,
  1. @echo off
  2. set n=3
  3. set /p n=输入几秒检测一次:
  4. set /a n=n+1
  5. if %n% leq 1 goto :eof
  6. :loop
  7. xcopy x1\*.* x2\ /d
  8. ping -n %n% 127.1 >nul
  9. goto :loop
复制代码

作者: 3Q3Q    时间: 2009-12-8 09:17

谢谢楼上各位朋友的回答,十分感激!这里有个问题还要麻烦大家(怪我没说清楚,不好意思呵呵):
1.X2文件夹将被定时执行操作,操作结束后将被清空,这样就无法对比出哪些文件已经被复制过。是否有其他的方法可以进行判断文件是否已被复制?
2.用文件的创建时间进行判断是否可行(精确到秒)?比如用一个变量记录下每次复制的一批文件中时间最新的一个,当下次执行复制操作时就可以以此时间变量为基准,只复制比这个时间更新的然后再次记录文件创建时间,这样循环下去...
希望您能给出代码,期待您的回复...
谢谢!!!
作者: bluewing009    时间: 2009-12-8 18:27     标题: 回复 6楼 的帖子

将已经复制的文件名导出为txt(或ini或者其他)即可,  复制时,用for 读取已复制文件名列表,if判断 copy 即可。
作者: neorobin    时间: 2009-12-8 20:58     标题: VBS 代码复制文件

干脆用 VBS 来做吧, 由于是无限循环, 要终止运行就 结束 WScript.exe 进程.
假设你的两个文件夹分别是 D:\x1  和 D:\x2   不是这样的话,对代码中相应改动就行了, 不然找不到目录会报错
无论用批还是用 vbs, 要适用于定时清空 x2 文件夹, 都需要一个文件列表记录文件(不能用变量, 文件太多会溢出内存)
适用于定时清空 x2 文件夹的
用创建日期和修改日期综合判断的(时间精确到秒), 这样代码还简单多了
PS: 我自己的机器上出现了不能覆盖文件的权限问题, 如果你也同样遇到, 请试试将本楼附件中的权限注册表文件导入
  1. SrcFolder = "D:\x1"
  2. DstFolder = "D:\x2"
  3. DateCOMLast = "0-1-1 00:00:00"
  4. DateCOMMax = DateCOMLast
  5. Do
  6.   CopyFiles SrcFolder, DstFolder, True, DateCOMLast
  7.   WScript.Sleep 60000 ' 等待时间 单位:ms 60000=1 分钟
  8. Loop Until false
  9. Function CopyFiles(Src, Dst, overwrite, ByRef DateCOMLast)
  10.    Dim fso, f, f1, fc
  11.    Set fso = CreateObject("Scripting.FileSystemObject")
  12.    Set f = fso.GetFolder(Src)
  13.    Set fc = f.Files
  14.    DateCOMMax = DateCOMLast
  15.    For Each f1 in fc ' 对源目录中的每一个文件进行 创建或修改 双重日期检测, 并确定是否复制
  16.      If DateDiff("s", DateCOMLast, f1.DateCreated) > 0 Or DateDiff("s", DateCOMLast, f1.DateLastModified) > 0 Then
  17.        f1.Copy Dst & "\" & f1.Name, overwrite
  18.        If  DateDiff("s", DateCOMMax, f1.DateCreated) > 0 Then DateCOMMax = f1.DateCreated            ' 计算一批文件中最新的创建日期
  19.        If  DateDiff("s", DateCOMMax, f1.DateLastModified) > 0 Then DateCOMMax = f1.DateLastModified  ' 或最新的修改日期
  20.      End If
  21.    Next
  22.    DateCOMLast = DateCOMMax ' WScript.Echo "DateCOMLast:" & DateCOMLast  完成一批新文件的复制后, 设置最新的创建或修改日期
  23. End Function
复制代码
用复制历史列表和存在性来决定的
  1. SrcFolder = "D:\x1"
  2. DstFolder = "D:\x2"
  3. FnList = "c:\FileList.txt"
  4. Const ForReading = 1, ForWriting = 2, ForAppending = 8
  5. Set fso = CreateObject("Scripting.FileSystemObject")
  6. If Not (fso.FileExists(FnList)) Then
  7.   Set FileList = fso.CreateTextFile(FnList, True)
  8.   FileList.Close
  9. End If
  10. Do
  11.   CopyFiles SrcFolder, DstFolder, True, FnList
  12.   WScript.Sleep 60000 ' 等待时间 单位:ms 60000=1 分钟
  13. Loop Until false
  14. Function CopyFiles(Src, Dst, overwrite, FList)
  15.    Dim fso, f, f1, fc
  16.    Set fso = CreateObject("Scripting.FileSystemObject")
  17.    Set f = fso.GetFolder(Src)
  18.    Set fc = f.Files
  19.    For Each f1 in fc ' 对源目录中的每一个文件进行 列表记录 和 实际文件 双重存在检测, 并确定是否复制
  20.      If Not FoundFileInList(FList, f1.Name) And Not (fso.FileExists(Dst & "\" & f1.Name)) Then
  21.        f1.Copy Dst & "\" & f1.Name, overwrite
  22.        Set fo = fso.OpenTextFile(FList, ForAppending, False)
  23.        fo.WriteLine f1.Name
  24.        fo.Close
  25.      End If
  26.    Next
  27. End Function
  28. Function FoundFileInList(listspec, filespec)
  29.    Const ForReading = 1
  30.    Dim fso, theFile, retstring
  31.    FoundFileInList = False
  32.    Set fso = CreateObject("Scripting.FileSystemObject")
  33.    Set theFile = fso.OpenTextFile(listspec, ForReading, False)
  34.    Do While theFile.AtEndOfStream <> True
  35.       if theFile.ReadLine = filespec then
  36.         FoundFileInList = True
  37.         theFile.Close
  38.         Exit Function
  39.       End If
  40.    Loop
  41.    theFile.Close
  42. End Function
复制代码
不适用于定时清空 x2 文件夹的
  1. SrcFolder = "D:\x1"
  2. DstFolder = "D:\x2"
  3. Do
  4.   CopyFiles SrcFolder, DstFolder, false
  5.   WScript.Sleep 60000 ' 等待 1 分钟
  6. Loop Until false
  7. Function CopyFiles(Src, Dst, overwrite)
  8.    Dim fso, f, f1, fc
  9.    Set fso = CreateObject("Scripting.FileSystemObject")
  10.    Set f = fso.GetFolder(Src)
  11.    Set fc = f.Files
  12.    For Each f1 in fc  
  13.       If Not (fso.FileExists(Dst & "\" & f1.Name)) Then
  14.         f1.Copy Dst & "\" & f1.Name, overwrite
  15.       End If   
  16.    Next
  17. End Function
复制代码

[ 本帖最后由 neorobin 于 2009-12-9 14:53 编辑 ]
作者: 3Q3Q    时间: 2009-12-9 09:31     标题: neorobin再麻烦您一下

If Not FoundFileInList(FList, f1.Name) And Not (fso.FileExists(Dst & "\" & f1.Name)) Then
这一句判断可否改成对文件创建时间的判断?(创建时间最好精确到分钟)  也就是说把每次复制的一批文件的创建时间进行对比,把时间最新的那个记录下来,下次复制操作时,以那个最新时间为标准只复制该时间后的文件,依次循环。。。。
因为源文件夹可能会在不同时间段接收的文件同名但不相同内容,用文件名列表做判断的话,不会对这些文件进行复制。。。
谢谢您了!!万分感激!

[ 本帖最后由 3Q3Q 于 2009-12-9 10:45 编辑 ]
作者: neorobin    时间: 2009-12-9 11:49     标题: 楼主请别急

事实上, 不管 BAT 还是 VBS 我都是肤浅得很啦, 楼主这样谢我, 我真不好意思. 嗯,我再考虑研究一下, 尽力向楼主所要求的方向改进了.
作者: netbenton    时间: 2009-12-9 12:35

建议楼主好研究下xcopy.exe ,或许它可以简单并高效的完成你的问题。。。
作者: caruko    时间: 2009-12-9 14:09

是哦..
你可以在新添加的文件上设置 存档属性,
然后 xcopy /m 就能判断有没有被复制..
或者 xcopy /d 来让命令自动判断目标文件夹是不是比 x1 里的旧
作者: caruko    时间: 2009-12-9 14:45

其实,还有一个很好用的工具..“公文包”
将X1文件夹拉到公文包里,X1文件夹下的任何改动,按一下更新就可以了
同样,公文包里的改动,也可以更新到X1文件夹下
作者: neorobin    时间: 2009-12-9 15:00     标题: 应楼主要求再改了一下

贴在 8 楼的最上面更新了

用创建日期和修改日期综合判断来确定是否复制源目录的每一个文件

不想再更复杂了, 所以有 2 个大的 不足:
1. 源目录中的子目录和子目录中的文件不能被复制;
2. 如果覆盖更新和目标目录中的文件访问(读,写,删除)同时发生, 可能会出错退出脚本

[ 本帖最后由 neorobin 于 2009-12-9 15:13 编辑 ]
作者: 3Q3Q    时间: 2009-12-9 16:15     标题: 回复 14楼 的帖子

啥也不说,先谢谢您!多谢您的帮助。我去试试。。。
作者: 3Q3Q    时间: 2009-12-9 16:37     标题: 回复 14楼 的帖子

在网上查了好多帖子都没有解决这个问题,现在终于解决了!谢谢大家的无私帮助,谢谢neorobin!尊重作者权益,转载请注明出处:)




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2