在csdn看到java对于文件夹拷贝的讨论,搬回blog,做一个备份。有空再写写中文注释。:)
javarule ( 2003-07-18) | ||
I have to say this is a very poor written OOP code. No wonder most people are doing Micrsoft ASP(because it is not OOP at all!). Here is the version I cooked for about 10-15 min of my time. public class DirCopyUtil { public static void copy(File src, File dest) throws IOException { getCopyable(src).copy(dest); } //this is the factory pattern. public static Copyable getCopyable(File src) { //if the source if file then return a file copier if (src.isFile()) { return new FileCopier(src); } /*else it has to be a directory copier, we could also enhance it to be other type of copier such as httpcopier etc...*/ return new DirCopier(src); } interface Copyable { void copy(File dest) throws IOException; } static class DirCopier implements Copyable { File srcDir; public DirCopier(File srcDir) { if (!srcDir.isDirectory()) { throw new IllegalArgumentException("passed in paremter has to be directory" + srcDir); } this.srcDir = srcDir; } /** * copy current directory content under 'destRoot' directory * @param destRoot the destination root directory, all the file and sub directory will be copied under this * destRoot directory, if destRoot doesn't exist, this will create the directory. * @throws IOException */ public void copy(File destRoot) throws IOException { // 1) if destRoot is not exist it will create it if (!destRoot.exists()) { if (!destRoot.mkdirs()) { throw new IOException("unable to create dir:" + destRoot); } } if (!destRoot.isDirectory()) { throw new IllegalArgumentException("passed in paremter has to be directory" + destRoot); } File[] dirContents = srcDir.listFiles(); //we know dirContents can not be null since only file will return null, so no need to check null for (int i = 0; i < dirContents.length; i++) { File _srcFile = dirContents[i]; String _srcPath = _srcFile.getCanonicalPath(); /*now I need to get the relative path question here is c:/abc/ cannonicalpath return "c:/abc" or "c://abc//"? the answer is "c://abc" so the following statement never executed, but I am just playing safe here since I don't know if every JVM implementation will behave the same as my XP machine and Sun 1.4 */ if (_srcPath.endsWith(File.separator)) { //the endswith has subtle bug, but it should not matter _srcPath = _srcPath.substring(0, _srcPath.length() - File.separator.length()); } File dest = new File(destRoot, _srcPath.substring(_srcPath.lastIndexOf(File.separatorChar) + 1)); //here I wire back to the factory method. getCopyable(dirContents[i]).copy(dest); } } } static class FileCopier implements Copyable { File src; public FileCopier(File src) { if (!src.isFile()) { throw new IllegalArgumentException("passed in paremter has to be file" + src); } this.src = src; } /** * Copy the current file to the dest file, if the dest file doesn't exist it will be created. * @param dest the destination file * @throws IOException */ public void copy(File dest) throws IOException { if (!dest.exists()) { dest.createNewFile(); } if (!dest.isFile()) { throw new IllegalArgumentException("passed in paremter has to be file" + dest); } //do straight file copy FileInputStream in = new FileInputStream(src); FileOutputStream out = new FileOutputStream(dest); byte[] buffer = new byte[1024 * 4]; //4k buffer int len = 0; while ((len = in.read(buffer, 0, buffer.length)) > 0) { out.write(buffer, 0, len); } in.close(); out.close(); } } } |