随笔-200  评论-148  文章-15  trackbacks-0
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();
        }
    }
}
posted on 2008-07-22 17:01 无声 阅读(374) 评论(0)  编辑  收藏 所属分类: 职场生活

只有注册用户登录后才能发表评论。


网站导航: