今天一个朋友让我帮他写个文件批量COPY的工具,我图方便就用JS写了,但遇到了些问题。
利用FSO写了一个批量COPY文件的程序。读取一个txt文件,txt文件中存有待复制的文件名称列表,格式为:
01.jpg
02.jpg
...一个文件放一行。这样没问题。
但假如文件列表中的文件名包含通配符,就不起作用了。比如:
01.jpg
02*.jpg
...任何以02开头的jpg文件都不会被copy过去。
我想要的结果就是:
假如我的源文件夹中有:
01.jpg
02.jpg
021.jpg
022123.jpg
03.jpg我希望把02.jpg,021.jpg,022123.jpg都copy到一个目标文件夹中。该如何做?
下面是我尝试的过程://使用打开的文件句柄.Copy;只能指定将要copy过去的目标文件名称。这个固然不行。
cf = fso.GetFile(sourceFile);
cf.Copy(targetFile);
//而使用CopyFile方法看似可以,但是其实也无法达到目的。
//假如sourceFile是一个包含通配符的文件名,target是一个目标文件夹,则会报没有权限的错误。
fso.CopyFile(sourceFile,target);
//假如sourceFile是一个包含通配符的文件名,而targetFile是一个固定文件名肯定也不行,因为它不知道copy过去后如何为文件命名
fso.CopyFile(sourceFile,targetFile);
查了文档,文档上说CopyFile的sourceFile可以包含通配符,但我觉得它的作用似乎是可以让路径中的文件夹包含通配符,但文件名包含通配符似乎有问题。
麻烦各位高手帮忙看一下。
下面是源代码,脚本有两种模式,第一种读取文件模式只要文件中不包含通配符是可用的,第二种暂时还没搞定,我想把这种使用通配符的模式单独处理:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
 <HEAD>
  <TITLE> 文件批量COPY工具</TITLE>
  <style type="text/css"> 
body {font: 62.5%/1.6 "Lucida Grande", "Lucida Sans", "Lucida Sans Unicode", Verdana, sans-serif; background-color:#AAFF00; margin:0;font-size: 12px;}
  </style><script language='javascript'>//改变模式
function changeMode( modeNo ){
switch( modeNo ){
case 0:
document.getElementById('mode').value = modeNo;
document.getElementById('loadfilediv').style.display = 'block';
document.getElementById('charmatcheddiv').style.display = 'none';
document.getElementById('changeMode1').disabled = true;
document.getElementById('changeMode2').disabled = false;
break;
case 1:
document.getElementById('mode').value = modeNo;
document.getElementById('loadfilediv').style.display = 'none';
document.getElementById('charmatcheddiv').style.display = 'block';
document.getElementById('changeMode2').disabled = true;
document.getElementById('changeMode1').disabled = false;
break;
default:
loadFileMode();
break;
}
}//创建FSO对象
var fso = new ActiveXObject("Scripting.FileSystemObject");//从文件中获取拷贝文件列表模式
function loadFileMode(){
//源文件夹
var sourceFolder = document.getElementById('sourceFolder').value;
//输出文件夹
var targetFolder = document.getElementById('targetFolder').value; //要复制的文件列表
var filelistfile = document.getElementById('filelistfile').value;
ts = fso.OpenTextFile(filelistfile,1);
var filelist = ts.ReadAll();
ts.close();
filelist = filelist.split("\r\n"); //打开源文件夹句柄
var f = fso.GetFolder(sourceFolder);
//获得文件列表
var fc = new Enumerator(f.files); //如果文件夹不存在则创建
if(!fso.FolderExists(targetFolder))
fso.CreateFolder(targetFolder); for (;!fc.atEnd();fc.moveNext()){
for(i=0;i<filelist.length;i++){
sourceFile = fso.BuildPath(sourceFolder,filelist[i]);
targetFile = fso.BuildPath(targetFolder,filelist[i]);
copyfile(sourceFile,targetFile);
}
}
}//通过模糊匹配获得文件列表模式(未完成)
function charMatchedMode(){
var filenamerule = document.getElementById('filenamerule').value;}
//拷贝文件
function copyfile( sourceFile, targetFile ){
//如果列表中指定文件存在就拷贝过去
if(fso.FileExists( sourceFile )){
cf = fso.GetFile(sourceFile);
cf.Copy(targetFile);
}
}//执行脚本
function init(){

var mode = document.getElementById('mode').value; switch( mode ){
case 0:
loadFileMode();
break;
case 1:
charMatchedMode();
break;
default:
loadFileMode();
break;
} alert('文件复制完成!');
}</script>
 </HEAD><BODY>
<H1>文件批量复制工具</H1><HR size='1' />
<input type='button' id='changeMode1' value='读取文件模式' onClick='changeMode(0);' /> || <input type='button' id='changeMode2' value='模糊匹配模式' onClick='changeMode(1);' />
<input type='hidden' id='mode' value='0' />
<div id='sourceFolderdiv'>源文件夹路径(类似:C:\sourceFolder,盘符要大写):<input id='sourceFolder' type='text' value='' /></div><br />
<div id='targetFolderdiv'>输出文件夹名称(类似:targetFolder.会创建在本脚本文件相同目录):<input id='targetFolder' type='text' value='' /></div><br />
<div id='charmatcheddiv'>文件名称模式:<input id='filenamerule' type='text' value='' /></div>
<div id='loadfilediv'>读取文件列表文件:<input id='filelistfile' type='file' value='' /></div>
<br />
<div><input type='button' value='COPY' onclick='init();' /></div><script>changeMode(0);</script><br /><br /><br />Code by cutefrog
 </BODY>
</HTML>

解决方案 »

  1.   

    再简单叙述下需求:假如我的待copy文件列表文件filelist.txt的内容如下:
    02*.jpg我的源文件夹有如下文件:
    01.jpg
    02.jpg
    021.jpg
    022123.jpg
    03.jpg我希望copy到newfiles文件夹的文件如下:
    02.jpg
    021.jpg
    022123.jpg
    该如何处理这个通配符的问题,请各位帮忙,感谢!
      

  2.   

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <HTML>
     <HEAD>
      <TITLE> 文件批量COPY工具</TITLE>
      <style type="text/css"> 
        body {font: 62.5%/1.6 "Lucida Grande", "Lucida Sans", "Lucida Sans Unicode", Verdana, sans-serif;margin:0;font-size: 12px;}
      </style><script language='javascript'>//改变模式
    function changeMode( modeNo ){
        switch( modeNo ){
            case 0:
                    document.getElementById('mode').value = modeNo;
                    document.getElementById('loadfilediv').style.display = 'block';
                    document.getElementById('charmatcheddiv').style.display = 'none';
                    document.getElementById('changeMode1').disabled = true;
                    document.getElementById('changeMode2').disabled = false;
                    break;
            case 1:
                    document.getElementById('mode').value = modeNo;
                    document.getElementById('loadfilediv').style.display = 'none';
                    document.getElementById('charmatcheddiv').style.display = 'block';
                    document.getElementById('changeMode2').disabled = true;
                    document.getElementById('changeMode1').disabled = false;
                    break;
            default:
                    loadFileMode();
                    break;
        }
    }//创建FSO对象
    var fso = new ActiveXObject("Scripting.FileSystemObject");//从文件中获取拷贝文件列表模式
    function loadFileMode(){
        //源文件夹
        var sourceFolder = document.getElementById('sourceFolder').value;
        //输出文件夹
        var targetFolder = document.getElementById('targetFolder').value;    //要复制的文件列表
        var filelistfile = document.getElementById('filelistfile').value;
        ts = fso.OpenTextFile(filelistfile,1);
        var filelist = ts.ReadAll();
        ts.close();
        filelist = filelist.split("\r\n");    //打开源文件夹句柄
        var f = fso.GetFolder(sourceFolder);
        //获得文件列表
        var fc = new Enumerator(f.files);    //如果文件夹不存在则创建
        if(!fso.FolderExists(targetFolder))
            fso.CreateFolder(targetFolder);    for (;!fc.atEnd();fc.moveNext()){
                for(i=0;i<filelist.length;i++){
                    sourceFile = fso.BuildPath(sourceFolder,filelist[i]);
                    targetFile = fso.BuildPath(targetFolder,filelist[i]);
                    copyfile(sourceFile,targetFile);
                }
        }
    }//通过模糊匹配获得文件列表模式(未完成)
    function charMatchedMode(){
        var filenamerule = document.getElementById('filenamerule').value;
        //源文件夹
        var sourceFolder = document.getElementById('sourceFolder').value;
        //输出文件夹
        var targetFolder = document.getElementById('targetFolder').value;    //如果文件夹不存在则创建
        if(!fso.FolderExists(targetFolder))
            fso.CreateFolder(targetFolder); sourceFile = fso.BuildPath(sourceFolder,filenamerule);
    targetFile = fso.BuildPath(targetFolder,'');
    fso.CopyFile(sourceFile,targetFile,true);}
    //拷贝文件
    function copyfile( sourceFile, targetFile ){
        //如果列表中指定文件存在就拷贝过去
        if(fso.FileExists( sourceFile )){
            cf = fso.GetFile(sourceFile);
            cf.Copy(targetFile);
        }
    }//执行脚本
    function init(){
        
        var mode = document.getElementById('mode').value;
        switch( mode ){//修改了条件为字符串
            case '0':
                    loadFileMode();
                    break;
            case '1':
                    charMatchedMode();
                    break;
            default:
                    loadFileMode();
                    break;
        }    alert('文件复制完成!');
    }</script>
     </HEAD><BODY>
    <H1>文件批量复制工具</H1><HR size='1' />
    <input type='button' id='changeMode1' value='读取文件模式' onClick='changeMode(0);' /> || <input type='button' id='changeMode2' value='模糊匹配模式' onClick='changeMode(1);' />
    <input type='hidden' id='mode' value='0' />
    <div id='sourceFolderdiv'>源文件夹路径(类似:C:\sourceFolder,盘符要大写):<input id='sourceFolder' type='text' value='' /></div><br />
    <div id='targetFolderdiv'>输出文件夹名称(类似:targetFolder.会创建在本脚本文件相同目录):<input id='targetFolder' type='text' value='' /></div><br />
    <div id='charmatcheddiv'>文件名称模式:<input id='filenamerule' type='text' value='' /></div>
    <div id='loadfilediv'>读取文件列表文件:<input id='filelistfile' type='file' value='' /></div>
    <br />
    <div><input type='button' value='COPY' onclick='init();' /></div><script>changeMode(0);</script><br /><br /><br />Code by cutefrog
     </BODY>
    </HTML>
      

  3.   

    用了你的文件名模式,不是用list模式,你要用list模式的话照着改一下就好了
    filenamerule=*.*
    可以成功
      

  4.   

    如果是本机操作的话,不用写网页了,写个VBS或JS脚本执行以下就可以了:  sourceFolder = InputBox("源文件夹路径(类似:C:\sourceFolder)", "sourceFolder", "C:\sourceFolder")
      targetfolder = InputBox("输出文件夹名称(类似:targetFolder.会创建在本脚本文件相同目录)", "targetfolder", "C:\targetFolder")
      filelist = InputBox("读取文件列表文件", "filelist", "C:\filelist")
      msgbox BatchCopyFile(sourceFolder, targetfolder, filelist)Function BatchCopyFile(ByVal sourceFolder, ByVal targetfolder, ByVal filelist)
      If sourceFolder = "" Or targetfolder = "" Or filelist = "" Then
        BatchCopyFile="请检查各输入参数,不能为空!": Exit Function
      end if
       Dim fso, myfile, FileName
       Set fso = CreateObject("Scripting.FileSystemObject")
       Set myfile = fso.OpenTextFile(filelist & ".txt", 1, False)
       Do While myfile.AtEndOfStream <> True
          FileName = myfile.ReadLine
          If InStr(FileName, "*") = 0 Then
            fso.copyfile sourceFolder & "\" & FileName, targetfolder & "\" & FileName
          Else
            strComputer = "."
            postfix = Right(FileName, InStrRev(FileName, ".") - 1)
            keyword = Replace(Split(FileName, ".")(0), "*", "")
            '这里也可以再创建一个FSO取代WMI代码
            Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
            Set colFiles = objWMIService.ExecQuery("ASSOCIATORS OF {Win32_Directory.Name='" & sourceFolder & "'} Where ResultClass = CIM_DataFile")
              For Each objFile In colFiles
                FileName = Right(objFile.Name, Len(objFile.Name) - InStrRev(objFile.Name, "\"))
                thisPostfix = Right(FileName, Len(objFile.Name) - InStrRev(objFile.Name, "."))
                
                If InStr(FileName, keyword) > 0 And thisPostfix = postfix Then
                  '这里没有针对通配符的位置做细致判断,仅仅举例而已.你自己再通盘考虑一下
                  strNewName = targetfolder & "\" & FileName
                  ret = objFile.Copy(strNewName)
                  If ret <> 0 Then
                    If errFilecopy = "" Then errFilecopy = FileName Else errFilecopy = errFilecopy & "," & FileName
                  End If
                End If
              Next
            
            Set colFiles = Nothing
            Set objWMIService = Nothing
          End If
       Loop
      myfile.Close
      Set myfile = Nothing
      Set fso = Nothing
      If errFilecopy <> "" Then BatchCopyFile = "拷贝出错的文件:" & errFilecopy Else BatchCopyFile = "完成!"End Function
    你也可以把它改为JS版的
      

  5.   

    哦,5楼代码要保存为 aaa.vbs,直接点击就可以了
      

  6.   

    非常感谢2楼和5楼。不过很奇怪,我昨天也是按照2楼那样的写法,但却不可以,可能是我没有使用BuildPath来构造targetFile的路径而是自己用字符串拼的。