黑马程序员技术交流社区

标题: 复制文件的问题 [打印本页]

作者: 张雪磊    时间: 2012-7-27 13:37
标题: 复制文件的问题
本帖最后由 张雪磊 于 2012-7-27 20:17 编辑

package com.itheima;

import java.io.*;

/*
需求: 编写一个程序,将d:\java 目录下的所有.java 文件复制到d:\jad 目录下,
                 并将原来文件的扩展名从.java 改为.jad
*/

public class Test9 {

        /**
         * @param args
         */
        public static void main(String[] args) throws IOException{
                // TODO Auto-generated method stub
                File dir=new File("d:\\java");
               
                String[] arr = dir.list(new FilenameFilter(){
                        public boolean accept(File dir,String name){
                                return name.endsWith(".java");
                        }
                });

               //在这行写了个输出语句 System.out.println(arr.length);结果打印正确,我在那个目录下放了5个java文件,打印的就是5
               
                for(int x=0;x<arr.length;x++){
                        BufferedReader bufr =
                                new BufferedReader(new FileReader("d:\\java\\"+arr[x]));
                        String[] arr1=arr[x].split(".");//到了这行                System.out.println(arr.length); 打印的结果就是0了,不知道为什么?
                        BufferedWriter bufw=
                                new BufferedWriter(new FileWriter("d:\\jad\\"+arr1[0]+".jad"));//这行报错说数组脚标越界
                        
                        String line=null;
                        while((line=bufr.readLine())!=null){
                                bufw.write(line);
                                bufw.flush();
                        }
                        bufw.close();
                        bufr.close();
                }

        }

}

报错:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
        at com.itheima.Test9.main(Test9.java:30)

不知道什么错的,找半天找不到问题!

作者: 王志明    时间: 2012-7-27 13:46
本帖最后由 王志明 于 2012-7-27 13:49 编辑

我前几天刚写过这道题,我定义了两个工具类,一个复制文件,一个过滤文件,而且灵活性也很好,可以通过参数定制来达到不同的目的:

  1. package com.itheima;

  2. import com.itheima.util.IOUtils;

  3. /**
  4. * 将d:\java 目录下的所有.java 文件复制到d:\jad 目录下,并将原来文件的扩展名从.java 改为.jad
  5. *
  6. * @author mrng
  7. *
  8. */
  9. public class Test9 {

  10.         public static void main(String[] args) throws Exception {

  11.                 /**
  12.                  * copyFilesAndChangeExtension(String srcDir, String extension, String
  13.                  * destDir, String newExtension, boolean searchSubDir)
  14.                  * 这个方法提供了强大的文件复制功能,通过不同的参数组合,可以达到各种效果
  15.                  *
  16.                  * srcDir指定要复制的目录 extension指定要复制的文件的扩展类型,如果不指定(""或null),将会复制指定目录下的所有文件
  17.                  * 还可以使用排除法(使用"!")过滤文件,比如,extension 的值为"!.java",那么除了".java"文件,其它的文件都将复制
  18.                  * destDir指定目的地目录
  19.                  * searchSubDir指定是否对指定目录的子孙目录下的文件也进行复制
  20.                  *
  21.                  */

  22.                 String srcDir = "src/com/itheima";
  23.                 String destDir = "src/copyFiles";

  24.                 //将xxx目录下的所有.java 文件复制到xxx目录下,并将原来文件的扩展名从.java 改为.jad
  25.                 IOUtils.copyFilesAndChangeExtension(srcDir, ".java",
  26.                                 destDir, ".jad", false);
  27.         }
  28. }
复制代码
工具类
  1. package com.itheima.util;

  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.FileOutputStream;
  5. import java.io.FilenameFilter;
  6. import java.io.IOException;
  7. import java.io.InputStream;
  8. import java.io.OutputStream;
  9. import java.util.ArrayList;
  10. import java.util.List;

  11. /**
  12. * IO 工具类
  13. *
  14. * @author mrng
  15. *
  16. */
  17. public class IOUtils {

  18.         /**
  19.          * 将指定文件拷贝到目的地 这里采用的是基础流(FileinputStream,FileOutputStream)+byte数组(缓冲区)实现
  20.          * 当然也可以使用包装流(Buffered....)
  21.          *
  22.          * @param src
  23.          *            将要拷贝的文件
  24.          * @param dest
  25.          *            将文件要保存到的目标目录
  26.          *
  27.          */
  28.         public static void copy(String src, String dest) {
  29.                 copy(src, dest, null);
  30.         }

  31.         /**
  32.          * copy(String src, String dest)的重载形式,可以更改文件扩展名
  33.          *
  34.          * @param src
  35.          * @param dest
  36.          * @param newExtension
  37.          */
  38.         public static void copy(String src, String dest, String newExtension) {
  39.                 File srcFile = new File(src);
  40.                 // 如果文件不存在或是一个目录,抛出异常
  41.                 if (!srcFile.exists() || srcFile.isDirectory())
  42.                         throw new RuntimeException("文件不存在");

  43.                 File destDir = new File(dest);
  44.                 // 如果目标目录不存在,则创建
  45.                 if (!destDir.exists()) {
  46.                         destDir.mkdirs();
  47.                 } else {
  48.                         // 如果是文件,抛出异常
  49.                         if (destDir.isFile()) {
  50.                                 throw new RuntimeException("您指定的目的地是一个文件,请重新指定目录");
  51.                         }
  52.                 }

  53.                 // 代表目标文件的完整路劲信息的对象
  54.                 File destFile = null;
  55.                 System.out.println();
  56.                 // 判断要不要改变文件的扩展名
  57.                 if (newExtension == null || newExtension.trim().equals("")) {
  58.                         // 不改变文件扩展名
  59.                         destFile = new File(dest + "/" + srcFile.getName());
  60.                 } else {
  61.                         // 改变文件扩展名
  62.                         // 如果文件没有扩展名,直接加上新的扩展名
  63.                         if (getExtension(srcFile.getPath()).equals("")) {
  64.                                 destFile = new File(dest + "/" + srcFile.getName()
  65.                                                 + newExtension);
  66.                         } else {
  67.                                 // 如果文件有扩展名,替换为新的扩展名
  68.                                 String newFilename = srcFile.getName();
  69.                                 newFilename = newFilename.substring(0,
  70.                                                 newFilename.lastIndexOf("."))
  71.                                                 + newExtension;
  72.                                 destFile = new File(dest + "/" + newFilename);
  73.                         }
  74.                 }

  75.                 InputStream is = null;
  76.                 OutputStream os = null;

  77.                 // 存放文件片段的缓冲区
  78.                 byte[] buf = new byte[1024 * 8];
  79.                 // 记录每次读取了多少byte数据
  80.                 int len;
  81.                 try {
  82.                         is = new FileInputStream(srcFile);
  83.                         os = new FileOutputStream(destFile);

  84.                         // 循环读取数据并写入到输出流
  85.                         while ((len = is.read(buf)) != -1) {
  86.                                 os.write(buf, 0, len);
  87.                         }

  88.                         System.out.println("拷贝成功!");
  89.                         System.out.println("文件\"" + srcFile.getName() + "\n\"已从\""
  90.                                         + srcFile.getAbsolutePath() + "\n拷贝到\""
  91.                                         + destFile.getAbsolutePath() + "\"");
  92.                 } catch (IOException e) {
  93.                         throw new RuntimeException("文件拷贝出现错误,请重试!");
  94.                 } finally {
  95.                         // 关闭流
  96.                         close(is, os);
  97.                 }
  98.         }

  99.         /**
  100.          * 获得文件的扩展名
  101.          *
  102.          * @param filePath
  103.          * @return
  104.          */
  105.         public static String getExtension(String filePath) {
  106.                 File file = new File(filePath);
  107.                 // 如果文件不存在,抛出异常
  108.                 if (!file.exists())
  109.                         throw new RuntimeException("文件不存在");

  110.                 // 得到文件名
  111.                 String fileName = file.getName();
  112.                 // 找出属于扩展名的那个“.”
  113.                 int index = fileName.lastIndexOf(".");
  114.                 // 如果文件没有扩展名,返回""
  115.                 if (index < 1) {
  116.                         return "";
  117.                 }
  118.                 // 截取扩展名部分
  119.                 String extension = fileName.substring(index, fileName.length());
  120.                 return extension;
  121.         }

  122.         /**
  123.          * 将指定目录下的文件(指定扩展名)复制到指定目录(可以更改扩展名)
  124.          *
  125.          * @param srcDir
  126.          *            源目录
  127.          * @param extension
  128.          *            要复制的文件的扩展名,如果不指定,就代表所有文件
  129.          * @param destDir
  130.          *            目标目录
  131.          * @param newExtension
  132.          *            新的扩展名
  133.          * @param searchSubDir
  134.          *            是否对指定的源目录下的子目录也执行相同的操作
  135.          */
  136.         public static void copyFilesAndChangeExtension(String srcDir,
  137.                         String extension, String destDir, String newExtension,
  138.                         boolean searchSubDir) {

  139.                 File srcFile = new File(srcDir);
  140.                 // 如果目录不存在或不是一个目录,抛出异常
  141.                 if (!srcFile.exists() || !srcFile.isDirectory())
  142.                         throw new RuntimeException("目录不存在");

  143.                 File newDestDir = new File(destDir);
  144.                 // 如果目标目录不存在,则创建
  145.                 if (!newDestDir.exists()) {
  146.                         newDestDir.mkdirs();
  147.                 } else {
  148.                         // 如果是文件,抛出异常
  149.                         if (newDestDir.isFile()) {
  150.                                 throw new RuntimeException("您指定的目的地是一个文件,请重新指定目录");
  151.                         }
  152.                 }

  153.                 // 文件清单
  154.                 List<File> fileList = new ArrayList<File>();
  155.                 // 获取指定目录的文件清单
  156.                 getDirList(fileList, srcFile, extension, searchSubDir,
  157.                                 new MyFilenameFilter());

  158.                 // 复制文件并更改扩展名
  159.                 for (File fiel : fileList) {
  160.                         copy(fiel.getPath(), newDestDir.getPath(), newExtension);
  161.                 }
  162.         }

  163.         /**
  164.          * 获得指定目录的文件清单
  165.          *
  166.          * @param fileList
  167.          *            保存文件清单的集合
  168.          * @param file
  169.          *            要获取文件清单的目录
  170.          * @param extension
  171.          *            扩展名,如果不指定,就代表所有文件
  172.          * @param searchSubDir
  173.          *            是否查找指定目录的子目录
  174.          * @param fileanmeFilter
  175.          *            文件名过率器
  176.          * @return 返回指定目录的文件清单
  177.          */
  178.         public static void getDirList(List<File> fileList, File file,
  179.                         String extension, boolean searchSubDir,
  180.                         FilenameFilter fileanmeFilter) {

  181.                 getDirList(fileList, file, extension, searchSubDir,
  182.                                 new MyFilenameFilter(), 0);
  183.         }

  184.         /**
  185.          * getDirList(List<File> fileList, File file, String extension, boolean
  186.          * searchSubDir, FilenameFilter fileanmeFilter) 的重载形式,多了一个功能性参数
  187.          *
  188.          * @param level
  189.          *            记录目录层级
  190.          */
  191.         private static void getDirList(List<File> fileList, File file,
  192.                         String extension, boolean searchSubDir,
  193.                         FilenameFilter fileanmeFilter, int level) {
  194.                 //目录层级+1
  195.                 level ++;

  196.                 // 如果file是目录就遍历
  197.                 if (file.isDirectory()) {
  198.                         File[] files = file.listFiles();

  199.                         if (files == null || files.length == 0) {
  200.                                 return;
  201.                         }

  202.                         // 如果需要查找指定目录的子目录,就递归
  203.                         if (level == 1 || searchSubDir == true) {
  204.                                 for (File f : files) {
  205.                                         getDirList(fileList, f, extension, searchSubDir,
  206.                                                         fileanmeFilter);
  207.                                 }
  208.                         }
  209.                 } else if (file.isFile()) {
  210.                         // 如果是文件并且extension已指定,就对其进行过滤
  211.                         if (extension != null && !extension.trim().equals("")) {
  212.                                 if (fileanmeFilter.accept(file, extension)) {
  213.                                         fileList.add(file);
  214.                                 }
  215.                         } else {
  216.                                 // 如果没有指定extension,不进行过滤
  217.                                 fileList.add(file);
  218.                         }
  219.                 }
  220.         }

  221.         /**
  222.          * 关闭流
  223.          */
  224.         private static void close(InputStream is, OutputStream os) {
  225.                 // 关闭流,如果关闭不成功,将流对象置为null
  226.                 if (is != null) {
  227.                         try {
  228.                                 is.close();
  229.                         } catch (IOException e) {
  230.                                 is = null;
  231.                                 e.printStackTrace();
  232.                         }
  233.                 }

  234.                 // 关闭流,如果关闭不成功,将流对象置为null
  235.                 if (os != null) {
  236.                         try {
  237.                                 is = null;
  238.                                 os.close();
  239.                         } catch (IOException e) {
  240.                                 e.printStackTrace();
  241.                         }
  242.                 }
  243.         }

  244. }
复制代码

作者: 王志明    时间: 2012-7-27 13:51
代码多,上一楼撑不下了,还差个文件过滤器
文件过滤器
  1. package com.itheima.util;

  2. import java.io.File;
  3. import java.io.FilenameFilter;

  4. /**
  5. * 此类可以根据扩展名过滤文件
  6. *
  7. * @author mrng
  8. *
  9. */
  10. public class MyFilenameFilter implements FilenameFilter {

  11.         /**
  12.          * 对指定文件进行过滤
  13.          *
  14.          * @param file
  15.          *            指定的文件
  16.          *
  17.          * @param extension
  18.          *            要过滤的扩展名 此参数有两种用法:
  19.          *            1,比如".java",如果文件扩展名为".java",返回true
  20.          *            2,比如"!.java",如果文件扩展名不是".java",则返回true
  21.          */
  22.         public boolean accept(File file, String extension) {

  23.                 // file==null直接返回false
  24.                 // 如果extension为null或"",那么调用这个方法没无意义了,返回false
  25.                 // 如果file不存在或是一个目录,返回false
  26.                 if (file == null || extension == null || "".equals(extension.trim())
  27.                                 || !file.exists() || file.isDirectory()) {
  28.                         return false;
  29.                 }

  30.                 // 获得文件的扩展名
  31.                 String fileExtension = IOUtils.getExtension(file.getPath());
  32.                  if (extension.startsWith("!")) {
  33.                         if (fileExtension.equals(extension.substring(1))) {
  34.                                 return false;
  35.                         }
  36.                         return true;
  37.                 } else {
  38.                         if (fileExtension.equals(extension)) {
  39.                                 return true;
  40.                         }
  41.                         return false;
  42.                 }
  43.         }
  44. }
复制代码

作者: 黑马连家华    时间: 2012-7-27 18:17
那么 我就就题论题
看看你的代码错在哪里

import java.io.*;

/*
需求: 编写一个程序,将d:\java 目录下的所有.java 文件复制到d:\jad 目录下,
                并将原来文件的扩展名从.java 改为.jad
*/

public class Help01 {

        /**
         * @param args
         */
        public static void main(String[] args) throws IOException{
                // TODO Auto-generated method stub
                File dir=new File("d:\\java");

                String[] arr = dir.list(new FilenameFilter(){
                        public boolean accept(File dir,String name){
                                return name.endsWith(".java");
                        }
                });
               //在这行写了个输出语句 System.out.println(arr.length);结果打印正确,我在那个目录下放了5个java文件,打印的就是5

                for(int x=0;x<arr.length;x++){
                        BufferedReader bufr =
                                new BufferedReader(new FileReader("d:\\java\\"+arr[x]));

                        String[] arr1=arr[x].split("\\.");//到了这行                System.out.println(arr.length); 打印的结果就是0了,不知道为什么?
                      //其实你的错误就出在了这里.没有被转义  至于你说的打印结果变成0了,你是不是把arr.length写成了arr1.length?我想下面那个错误你也应该知道问题出在哪里了
                        BufferedWriter bufw=
                                new BufferedWriter(new FileWriter("d:\\jad\\"+arr1[0]+".jad"));//这行报错说数组脚标越界

                        String line=null;
                        while((line=bufr.readLine())!=null){
                                bufw.write(line);
                                bufw.flush();
                        }
                        bufw.close();
                        bufr.close();
                }

        }

}


作者: 黑马连家华    时间: 2012-7-27 18:22
忘了解释: "."为什么要被转义呢?
通过查阅API可以知道,String的split方法接收的是一个正则表达式,"."在正则表达式里面代表的是任意字符.单纯的想要使用"."这个字符 就需要被转义

还是...给好评哦




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2