A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

复制文件夹我的思路是先创建子目录中所有的文件夹,再复制文件
在创建文件夹的时候,先获取原文件夹的绝对路径,再修改这个路径创建文件夹
String s = file.getAbsolutePath();   得到源的绝对路径
当对其修改时一开我使用的是
假设源在d盘的一个目录下,复制到e盘下
只要改变盘符即可
s = s.replaceFirst("d:\\", "e:\\");
报错
Exception in thread "main" java.util.regex.PatternSyntaxException: Unexpected internal error near index 3
d:\
   ^

大家可以想想怎么解决,不用StringBuilder

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

16 个回复

倒序浏览
本帖最后由 周素强 于 2012-5-6 13:51 编辑

我用递归法做一个复制文件夹 不知是不是你要的效果。
  1.         public static void copyFiles(File yDir,File mDir)//yDir资源目录,mDir目标目录
  2.         {
  3.                 //System.out.println(yDir);
  4.                 File[] files = yDir.listFiles();
  5.                 for(int x=0; x<files.length; x++)
  6.                 {
  7.                         if(files[x].isDirectory())//判断是否为目录
  8.                         {
  9.                                 File f = new File(mDir.toString()+"\\"+files[x].getName());//获取资源目录下的建子文件夹名
  10.                                 f.mkdir();//在目标地址下创建子文件夹
  11.                                 copyFiles(files[x],f);//递归法调用自身
  12.                         }
  13.                         else
  14.                                 copyFile(files[x],mDir);//调用复制文件的方法
  15.                 }
  16.         }
  17.         
  18.         public static void copyFile(File f1,File f2)//f1表示资源文件,f2表示目标目录
  19.         {
  20.                 BufferedInputStream bis = null;
  21.                 BufferedOutputStream bos = null;
  22.                 try
  23.                 {
  24.                         
  25.                         bis =new BufferedInputStream(new FileInputStream(f1));
  26.                         bos =new BufferedOutputStream(new FileOutputStream(f2.toString()+"\\"+f1.getName()));
  27.                         byte[] buf = new byte[1024];
  28.                         int len = 0;
  29.                         while((len=bis.read(buf))!=-1)
  30.                         {
  31.                                 bos.write(buf);
  32.                         }
  33.                 }
  34.                 catch (IOException e)
  35.                 {
  36.                         throw new RuntimeException("拷贝文件失败!");
  37.                 }
  38.                 finally
  39.                 {
  40.                         try
  41.                         {
  42.                                 if (bis!=null)
  43.                                         bis.close();                                
  44.                         }
  45.                         catch (IOException e)
  46.                         {
  47.                                 throw new RuntimeException("关闭读取流失败!");
  48.                         }
  49.                         try
  50.                         {
  51.                                 if (bos!=null)
  52.                                         bos.close();                                
  53.                         }
  54.                         catch (IOException e)
  55.                         {
  56.                                 throw new RuntimeException("关闭写入流失败!");
  57.                         }
  58.                 }
  59.         }
复制代码

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

回复 使用道具 举报
关于楼主遇到的错误,我的看法是:
楼主替换盘符的时候用了replaceFirst,但是这个函数的参数是(String regex,String replacement),第一个参数是正则表达式
所以楼主这里用的d:\\中的\\表示了back转义字符,编译器判断你的正则表达式语法错误,因此报错是 PatternSyntaxException

我觉得直接用replace会好一些。

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

回复 使用道具 举报
来学习下,我也有同样的疑惑点。
回复 使用道具 举报
2楼的方法我借鉴下 换盘符的思路学习下
这个问题只要
s = s.replaceFirst("d:\\\\", "e:\\\\");
就可以了
我的理解是
\\ 转义了后面那个"\"
而replaceFirst替换的是相同的字符串
File file = new File("d:\\da.txt");
新建对象中的字符串是d:\\
替换时就需要用两次转义将"\"变成对象目录中的两个"\"
没说清楚,高手指点
回复 使用道具 举报
周素强 发表于 2012-5-6 13:47
我用递归法做一个复制文件夹 不知是不是你要的效果。

2l你的方法试验成功了吗?我觉得有问题,运行不成功 我写的时候也遇到过这个情况,不能拷贝文件
回复 使用道具 举报
倪杭乘 发表于 2012-5-6 14:35
2l你的方法试验成功了吗?我觉得有问题,运行不成功 我写的时候也遇到过这个情况,不能拷贝文件 ...

成功了啊,你把代码复制再加个主函数调用一下试试
回复 使用道具 举报
周素强 发表于 2012-5-6 14:40
成功了啊,你把代码复制再加个主函数调用一下试试

14行报错,无法拷贝,这两行注释,我打印了文件夹目录,目录是对的 但是没有创建文件夹
回复 使用道具 举报
倪杭乘 发表于 2012-5-6 15:01
14行报错,无法拷贝,这两行注释,我打印了文件夹目录,目录是对的 但是没有创建文件夹 ...

               public static void main(String[] args)
        {
                File f1 = new File("F:\\java_Example");
                File f2 = new File("F:\\copy");
                copyFiles(f1,f2);
        }
主函数调用 没有出错啊?是不是你传目录传错了 ,我这个程序没有创建资源目录的父目录也就是我上面主函数的java_Example文件夹
回复 使用道具 举报
别人写递归,我就就想写非递归实现  
讨论讨论, 毕竟递归效率低,这是通过栈技术的深度搜索创建文件夹,创建文件和拷贝文件的
能处理一般遇到的所有文件,考虑了各种意外情况(没注意到的,各位指正哈 )
楼主可以试试噢,有问题,继续交流
直接上代码了:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Stack;

public class Test
{
        public static void main(String[] args)
        {
                String resDir = "C:\\Win-TC";
                String desDir = resDir.replaceFirst("C", "E");
               
                //System.out.println(desDir);
                boolean isSuccessed = copyDir(desDir, resDir); //提供源文件夹路径, 目标文件夹地址 ,可以为任意
                if(isSuccessed)
                        System.out.println("文件夹复制成功!!");
                else
                        System.out.println("文件夹复制失败!!");
        }
        public static boolean copyDir(String desDir, String resDir)
        {
                File file = new File(resDir);
                if(resDir == null || (!file.isFile() && !file.isDirectory())) //如果resDir为空或非法则返回false
                {
                        System.out.println("源文件非法");
                        return false;
                }
                if(file.isFile())  //如果是文件则直接复制
                {
                        try {
                                File temp = new File(desDir);
                                temp.createNewFile();
                                return copyFile(temp, file);
                        } catch (Exception e) {
                                e.printStackTrace();
                                return false;
                        }
                }
                //利用深度优先复制文件,
                Stack<File> stack = new Stack<File>(); //定义栈,栈中只存放文件夹(目录)
                stack.push(file); //将第一个文件夹压栈
               
                while(!stack.isEmpty())
                {
                        File rDir = stack.pop(); // 源文件夹
                        File dDir = changeResToDes(rDir, desDir, resDir); // 获取源文件夹的绝对路径,并且替换为目的文件夹的路径
                        if(!dDir.exists()) //若不存在则创建,存在继续
                                dDir.mkdirs();
                        for(File f : rDir.listFiles())  //对源文件夹迭代
                        {
                                if(f.isFile())  //如果是文件就拷贝
                                {
                                        boolean isSuccessed = copyFile(changeResToDes(f, desDir, resDir) , f);
                                        if(!isSuccessed)  //如果文件复制失败,则直接返回false
                                                return false;
                                }
                                else//否则对文件夹进行压栈
                                        stack.push(f);
                        }
                }
                return true;
        }
        public static boolean copyFile(File desPath, File resPath)  //对给定的文件进行复制
        {
                try {
                        if(!desPath.exists())
                                desPath.createNewFile();
                } catch (Exception e) {
                        e.printStackTrace();
                        System.out.println("文件创建失败!!");
                        return false;
                }
                byte[] buffer = new byte[8 * 1024];
                InputStream in = null;
                OutputStream os = null;
                try {
                        in = new FileInputStream(resPath);
                        os = new FileOutputStream(desPath);
                        int len = -1;
                        while((len = in.read(buffer)) != -1)
                        {
                                os.write(buffer, 0, len);
                        }
                        os.flush();
                } catch (Exception e) {
                        e.printStackTrace();
                        System.out.println("文件复制失败!");
                        return false;
                }finally{
                        try {
                                if(in != null)
                                        in.close();
                                if(os != null)
                                        os.close();
                        } catch (Exception e2) {
                                e2.printStackTrace();
                        }
                }
                return true;
        }
        public static File changeResToDes(File file ,String desDir, String resDir)// 获取源文件夹的绝对路径,并且替换为目的文件夹的路径
        {
                File temp = new File(file.getAbsolutePath().replace(resDir, desDir));
                //System.out.println("转化文件:"+file.getAbsolutePath()+"到:"+temp.getAbsolutePath());
                return temp;
        }
}

花了半个小时啊,版主加分啊。。。
回复 使用道具 举报
周素强 发表于 2012-5-6 16:55
public static void main(String[] args)
        {
                File f1 = new File("F:\\java_Example") ...

我知道了,你这个的目标目录是要存在才行,我传了个没有存在的目标就报错了
回复 使用道具 举报
徐慧书 发表于 2012-5-6 18:01
别人写递归,我就就想写非递归实现  
讨论讨论, 毕竟递归效率低,这是通过栈技术的深度搜索创建文件夹,创 ...

这个很厉害,stack暂时还没学到,留着以后看 :)
回复 使用道具 举报
倪杭乘 发表于 2012-5-6 18:43
我知道了,你这个的目标目录是要存在才行,我传了个没有存在的目标就报错了 ...

恩,是啊,不过那是对于文件,若是按你标题要求,拷贝文件夹是没有任何问题的。
如果文件那需要加几句代码修改如下
if(file.isFile())  //如果是文件则直接复制
                {
                        try {
                                File temp = new File(desDir);       
                                                   //添加这几句代码表示 为目标文件先建立其文件夹
                                File temp_dir = temp.getParentFile();
                                if(temp_dir != null && !temp_dir.exists())
                                        temp_dir.mkdirs();
                                temp.createNewFile();
                                return copyFile(temp, file);

有问题继续讨论噢
回复 使用道具 举报
倪杭乘 发表于 2012-5-6 18:45
这个很厉害,stack暂时还没学到,留着以后看

其实这个stack 还是进黑马论坛才用过两次,只是按照stack的思想去写,java提供的东西很方便,所以写起来也很快。加油黑马
回复 使用道具 举报
10楼的真的很猛,该方法很好用,Stact栈暂时还没有学到,以后来研究下
回复 使用道具 举报
  1. import java.io.File;
  2. import java.io.FileInputStream;
  3. import java.io.FileOutputStream;
  4. import java.io.IOException;

  5. public class CopyDemo {
  6.         //带\
  7.         static String StringOolDir=null;
  8.         public final static char LINE=System.getProperty("file.separator").toCharArray()[0];
  9.         /**
  10.          * @param args
  11.          * @throws IOException
  12.          *
  13.          *  需求:拷贝文件到指定目录 并且保留文件结构
  14.          *  思路:
  15.          *          1.递归文件 获取目录
  16.          *          2.获取目录绝对路径
  17.          *          3.用indexOf获取第一个\出现位置
  18.          *          4.subString 获取\之后的路径
  19.          *          5.创建File路径对象 指定路径加获取的路径
  20.          *          6.创建新路径
  21.          *          7.拷贝文件
  22.          */
  23.         public static void main(String[] args){
  24.                 String soldFile=new String("f:\\1");
  25.                 String snewFile=new String("c:"+LINE);
  26.                 temp(soldFile,snewFile);
  27.         }
  28.         private static void temp(String soldFile, String snewFile) {
  29.                 //备份一份被拷贝文件的主目录
  30.                 StringOolDir=soldFile.substring(soldFile.lastIndexOf(LINE));
  31.                 copy(soldFile,snewFile);
  32.         }
  33.         private static void copy(String soldFile, String snewFile) {
  34.                 File oldFile=new File(soldFile);
  35.                 //检查被拷贝文件是否存在       
  36.                 //生成新的路径 拷贝到的目的路径+被拷贝文件目录名
  37.                 String path=snewFile.concat(oldFile.getAbsolutePath().substring(StringOolDir.length()));
  38.                 if(!oldFile.exists())
  39.                 {
  40.                         throw new RuntimeException("拷贝路径不存在!0x001");
  41.                 }
  42.                 if(oldFile.isFile())
  43.                 {       
  44.                         FileInputStream fis=null;
  45.                         FileOutputStream fos=null;
  46.                         //文件名 带\
  47.                         String filename=path.substring(path.lastIndexOf(LINE));
  48.                         //文件路径 不带\
  49.                         File dir=new File(path.substring(0,path.lastIndexOf(LINE)));
  50.                         if(!dir.exists())
  51.                                 dir.mkdirs();
  52.                         try {
  53.                                 fis=new FileInputStream(oldFile);
  54.                                 fos=new FileOutputStream(new File(dir,filename));
  55.                                 byte[] arr=new byte[1024];
  56.                                 int index;
  57.                                 while((index=fis.read(arr))!=-1)
  58.                                 {
  59.                                         fos.write(arr,0,index);
  60.                                 }
  61.                         } catch (Exception e) {
  62.                                 throw new RuntimeException("指定目录错误!0x002");
  63.                                 // TODO: handle exception
  64.                         }
  65.                         finally
  66.                         {

  67.                                 if(fos!=null)
  68.                                 {
  69.                                         try {
  70.                                                 fos.close();
  71.                                         } catch (IOException e) {
  72.                                                 throw new RuntimeException("系统错误!0x003");
  73.                                         }
  74.                                         finally
  75.                                         {
  76.                                                 try {
  77.                                                         fis.close();
  78.                                                 } catch (IOException e) {
  79.                                                         throw new RuntimeException("系统错误!0x004");
  80.                                                 }
  81.                                         }
  82.                                 }
  83.                         }
  84.                 }
  85.                 else
  86.                 {
  87.                         //为空目录未创建
  88.                         File[] files= oldFile.listFiles();
  89.                         if(files.length==0)
  90.                                 new File(path).mkdirs();
  91.                         for(File f:files)
  92.                         {
  93.                                 copy(f.getAbsolutePath(),snewFile);
  94.                         }
  95.                        
  96.                 }
  97.         }
复制代码
我也是刚刚学IO和递归 不懂栈技术 用递归实现了这个功能
回复 使用道具 举报
哇塞 好厉害啊
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马