Package org.chaidb.db.helper

Source Code of org.chaidb.db.helper.FileUtil

/*
* Copyright (C) 2006  http://www.chaidb.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
*/
package org.chaidb.db.helper;

import org.apache.log4j.Logger;

import java.io.*;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

/**
* Implements some file system related utility methods in a platform independent
* manner.
*/
public class FileUtil {
    public static final String ZIP = ".zip";
    private static final Logger logger = Logger.getLogger(FileUtil.class);

    /**
     * File separator on this platform
     */
    public static final String FILE_SEPARATOR = System.getProperty("file.separator");

    /**
     * deletes a file or a directory including all files and sub-directories
     *
     * @param tbrDir The file/directory to be removed
     * @return A boolean flag indicating whether the file has been deleted
     *         successfully
     */
    public static boolean removeFileOrDirectory(File tbrDir) {
        if (!tbrDir.isDirectory()) {
            return tbrDir.delete();
        }
        String[] filesTbd = tbrDir.list();
        if (filesTbd != null) {
            for (int i = 0; i < filesTbd.length; i++) {
                String f_str = tbrDir.getAbsolutePath() + FILE_SEPARATOR + filesTbd[i];
/*              if (f_str.indexOf(":")>0) {
                    f_str = f_str.substring(f_str.indexOf(":")+1);
                }
*/
                File tbd = new File(f_str);
                if (tbd.isDirectory()) {
                    if (!removeFileOrDirectory(tbd)) return false;
                } else {
                    if (!tbd.delete()) return false;
                }
            }
        }
        return tbrDir.delete();
    }

    public static boolean removeFiles(File tbrDir, String regEx) {
        if (!tbrDir.isDirectory()) {
            if (matchPattern(tbrDir.getName(), regEx)) {
                return tbrDir.delete();
            } else {
                return true;
            }
        }
        String[] filesTbd = tbrDir.list();
        if (filesTbd != null) {
            for (int i = 0; i < filesTbd.length; i++) {
                String f_str = tbrDir.getAbsolutePath() + FILE_SEPARATOR + filesTbd[i];
/*              if (f_str.indexOf(":")>0) {
                    f_str = f_str.substring(f_str.indexOf(":")+1);
                }
*/
                File tbd = new File(f_str);
                if (tbd.isDirectory()) {
                    if (!removeFiles(tbd, regEx)) return false;
                } else {
                    if (matchPattern(tbd.getName(), regEx)) {
                        if (!tbd.delete()) return false;
                    }
                }
            }
        }
        return true;
    }

    public static boolean matchPattern(String fileName, String regex) {
        if (regex == null) return true;
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(fileName);
        return m.matches();
    }

    public static long getFileOrDirectorySize(File tbrDir) {
        long size = 0;
        if (!tbrDir.isDirectory()) {
            size = size + tbrDir.length();
        } else {
            String[] filesTbd = tbrDir.list();
            if (filesTbd != null) {
                for (int i = 0; i < filesTbd.length; i++) {
                    String f_str = tbrDir.getAbsolutePath() + FILE_SEPARATOR + filesTbd[i];
                    File tbd = new File(f_str);
                    if (tbd.isDirectory()) {
                        size = size + getFileOrDirectorySize(tbd);
                    } else {
                        size = size + tbd.length();
                    }
                }
            }
        }
        return size;
    }

    public static boolean emptyDirectory(File dir, boolean recursive) {
        if (!dir.isDirectory()) {
            return false;
        }
        File[] files = dir.listFiles();
        if (files == null) {
            return false;
        }

        for (int i = 0; i < files.length; i++) {
            if (files[i].isDirectory() && recursive) {
                if (!emptyDirectory(files[i], recursive)) return false;
            } else {
                if (!files[i].delete()) return false;
            }
        }
        return true;
    }

    public static boolean removeDirectory(String dir) {
        File dirFile = new File(dir);
        if (!dirFile.isDirectory()) return false;
        return removeFileOrDirectory(dirFile);
    }

    /**
     * saves file as dir/fileName
     *
     * @param dir      The dir to save the file
     * @param fileName The file name
     * @param in       The inputstream which holds the content of the file
     */
    public static void saveFile(String dir, String fileName, InputStream in) throws IOException {
        FileOutputStream out = new FileOutputStream(new File(dir + File.separator + fileName));
        byte[] buf = new byte[1024];
        int ret = in.read(buf);
        while (ret > 0) {
            out.write(buf, 0, ret);
            ret = in.read(buf);
        }
        out.close();
        in.close();
    }

    public static void saveFile(String filePath, InputStream in) throws IOException {
        FileOutputStream out = new FileOutputStream(new File(filePath));
        byte[] buf = new byte[1024];
        int ret = in.read(buf);
        while (ret > 0) {
            out.write(buf, 0, ret);
            ret = in.read(buf);
        }
        out.close();
        in.close();
    }

    public static void saveFile(String filePath, String content) throws IOException {
        FileOutputStream out = new FileOutputStream(filePath);
        byte[] data = null;
        try {
            data = content.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
        }
        out.write(data);
        out.close();
    }

    /**
     * reads the entire contents of a file and returns them as a byte array
     *
     * @param file The file whose contents are to be read
     * @throws IOException Exception while reading from the input file
     */
    public static byte[] readFileContents(File file) throws IOException {
        FileInputStream fis = new FileInputStream(file);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int available = fis.available();
        while (available > 0) {
            byte[] availableBytes = new byte[available];
            int bytesRead = fis.read(availableBytes);
            baos.write(availableBytes, 0, bytesRead);
            available = fis.available();
        }
        fis.close();
        return baos.toByteArray();
    }


    public static void copyFile(String srcName, String destName) throws IOException {
        FileInputStream fi = null;
        FileOutputStream fo = null;
        long lastMT = new File(srcName).lastModified();
        try {
            fi = new FileInputStream(srcName);
            fo = new FileOutputStream(destName);
            byte[] buff = new byte[4096];
            while (true) {
                int nReaded = fi.read(buff);
                if (nReaded < 0) {
                    break;
                }
                fo.write(buff, 0, nReaded);
            }
            fo.close();
            fo = null;
            new File(destName).setLastModified(lastMT);
        } finally {
            if (fi != null) {
                try {
                    fi.close();
                } catch (Exception e) {

                }
            }

            if (fo != null) {
                try {
                    fo.close();
                } catch (Exception e) {

                }
            }

        }
    }

    public static void copyDirectory(String srcName, String destName) throws IOException {
        File srcDir = new File(srcName);
        if (!srcDir.isDirectory()) throw new IOException("Source file: " + srcName + " is not a directory");
        File destDir = new File(destName);

        if (!destDir.exists()) {
            if (!destDir.mkdirs()) throw new IOException("Can't create destination directory:" + destName);
        }

        File[] srcFiles = srcDir.listFiles();
//        String localDir = srcDir.getAbsolutePath();

        if (srcFiles != null) {
            for (int i = 0; i < srcFiles.length; i++) {
                String destFileName = destName + File.separatorChar + srcFiles[i].getName();
                if (srcFiles[i].isDirectory()) {
                    copyDirectory(srcFiles[i].toString(), destFileName);
                } else {
                    copyFile(srcFiles[i].toString(), destFileName);
                }
            }
        }
    }


    /* copy source file from srcFrom to srcTo, srcTo is excluded */
    public static boolean copyFile(String srcName, long srcFrom, long srcTo, String dstName, long dstFrom) throws IOException {
        RandomAccessFile fSrc = null;
        RandomAccessFile fDst = null;
        try {
            int BLOCKSIZE = 4096;
            byte[] buf = new byte[BLOCKSIZE];
            fSrc = new RandomAccessFile(srcName, "r");
            fDst = new RandomAccessFile(dstName, "rw");
            fSrc.seek(srcFrom);
            fDst.seek(dstFrom);
            int size;
            long len = srcTo - srcFrom;

            while (len > 0) {
                if (len > BLOCKSIZE) size = BLOCKSIZE;
                else size = (int) len;
                size = fSrc.read(buf, 0, size);
                if (size < 0) break//have error
                fDst.write(buf, 0, size);
                len = len - size;
            }
        } finally {
            try {
                if (fSrc != null) fSrc.close();

                if (fDst != null) fDst.close();
            } catch (IOException ioe) {
                throw ioe;
            }
        } //finally
        return true;
    }


    /**
     * copy file from sSrcFileName into sDstFileName and the postion from
     * lStart to lEnd, if the sDstFileName exist zip file then unzip it.
     * After do it, it will exist the sDstFileName file, and if there the zip file,
     * it will delete it.
     *
     * @param sSrcFileName
     * @param lFrom
     * @param lTo
     * @param sDstFileName
     */
    public static void copyFile(String sSrcFileName, long lFrom, long lTo, String sDstFileName) throws FileNotFoundException, IOException {
        if (hasZipFile(sDstFileName)) {
            unzipFile(sDstFileName, 0, sDstFileName);
            File f = new File(sDstFileName + ZIP);
            f.delete();
        }
        copyFile(sSrcFileName, lFrom, lTo, sDstFileName, lFrom);
    }


    /**
     * write fully lCount data to the out.
     * Try read from input, if there are no datas to read then using padded data
     * to fill untill the out data reached lCount length.
     *
     * @param input
     * @param lCount
     * @param out
     * @param nBufferSize buffer length
     * @param data        temporary data buffer, it's used for improve program performance.
     * @throws IOException
     */
    private static void writeFully(InputStream input, long lCount, OutputStream out, int nBufferSize, byte[] data) throws IOException {
        if (lCount <= 0) {
            return;
        }

        long lReserved = lCount;
        int nShouldRead = 0;
        while (true) {
            //caculate should read
            if (lReserved >= nBufferSize) {
                nShouldRead = nBufferSize;
            } else {
                nShouldRead = (int) lReserved;
            }

            int nReaded = input.read(data, 0, nShouldRead);

            //If can read then read and write, else use 0 to padded it.
            if (nReaded != -1) {
                out.write(data, 0, nReaded);
                lReserved -= nReaded;
            } else {
                Arrays.fill(data, (byte) 0);
                out.write(data, 0, nShouldRead);
                lReserved -= nShouldRead;
            }

            if (lReserved == 0) {
                break;
            }
        }//end while

    }


    /**
     * write fully lCount data to the out.
     * Using padded data to fill untill the out data reached lCount length.
     *
     * @param lCount
     * @param out
     * @param nBufferSize buffer length
     * @param data        temporary data buffer, it's used for improve program performance.
     * @throws IOException
     */
    private static void writeFully(long lCount, OutputStream out, int nBufferSize, byte[] data) throws IOException {
        if (lCount <= 0) {
            return;
        }

        Arrays.fill(data, (byte) 0);
        long lReserved = lCount;
        int nShouldWrite = 0;
        while (true) {
            //caculate should read
            if (lReserved >= nBufferSize) {
                nShouldWrite = nBufferSize;
            } else {
                nShouldWrite = (int) lReserved;
            }

            out.write(data, 0, nShouldWrite);
            lReserved -= nShouldWrite;

            if (lReserved == 0) {
                break;
            }
        }//end while
    }


    /**
     * zip the sSrcFileName from lStart into the sDstFileName.
     * If the unzip sDestFileName has been existed, you should first read the unzip
     * dest file which readed length is lStart, and then zip it, the unzip
     * sDestFileName should delete.
     *
     * @param sSrcFileName source file name
     * @param lStart       start position, it's also the destination file's start position
     * @param sDstFileName destionation file, the file name isn't end with .zip,
     *                     but aftered ziped, the filename will be added .zip.
     */
    public static void zipFile(String sSrcFileName, long lStart, String sDstFileName) throws FileNotFoundException, IOException {
        int nBufferSize = 4096;

        FileOutputStream dest = null;
        ZipOutputStream out = null;

        BufferedInputStream bis = null;
        File fDstFile = null;

        if (hasZipFile(sDstFileName)) {
            unzipFile(sDstFileName, 0, sDstFileName);
        }

        IOException ioe = null;

        try {
            dest = new FileOutputStream(sDstFileName + ZIP);
            out = new ZipOutputStream(new BufferedOutputStream(dest));
            ZipEntry entry = new ZipEntry(sDstFileName);
            out.putNextEntry(entry);

            bis = new BufferedInputStream(new FileInputStream(sSrcFileName), nBufferSize);
            bis.skip(lStart);

            byte[] data = new byte[nBufferSize];

            //It has combined the dest file if it exists or filled char after
            //executed the following codes.
            fDstFile = new File(sDstFileName);

            if (lStart > 0) {
                if (fDstFile.exists()) {
                    FileInputStream normalFile = new FileInputStream(fDstFile);
                    writeFully(normalFile, lStart, out, nBufferSize, data);
                    normalFile.close();
                }//end if
                else {
                    writeFully(lStart, out, nBufferSize, data);
                }//end else
            }
            //read from sSrcFileName into the sDstFileName
            while (true) {
                int nByte = bis.read(data);
                if (nByte == -1) {
                    break;
                }

                out.write(data, 0, nByte);
            }//end while
        } catch (IOException ioe1) {
            ioe = ioe1;
        } finally {
            try {
                if (bis != null) {
                    bis.close();
                }

                if (out != null) {
                    out.close();
                }

                if (dest != null) {
                    dest.close();
                }
            } catch (Exception e) {

            }
        }//end finally

        if (ioe != null) {
//if zip file failed, we should delete the zip file
            try {
                if (hasZipFile(sDstFileName)) {
                    File f = new File(sDstFileName + ZIP);
                    f.delete();
                }
            } catch (Exception e) {

            }
            throw ioe;
        }

        if (fDstFile != null) {
            fDstFile.delete();
        }
    }


    /**
     * unzip the sSrcFileName.zip into the sDstFileName, the length is lLen.
     *
     * @param sSrcFileName which will be added .zip extention
     * @param lLen         unzip till to the length
     * @param sDstFileName Destination file name which has no .zip
     * @throws FileNotFoundException
     * @throws IOException
     */
    public static void unzipFile(String sSrcFileName, String sDstFileName, long lLen) throws FileNotFoundException, IOException {
        int nBufferSize = 4096;

        FileOutputStream dest = null;
        BufferedInputStream bis = null;
        ZipFile zipFile = null;
        IOException ioe = null;
        byte[] data = null;
        try {
            zipFile = new ZipFile(sSrcFileName + ZIP);
            Enumeration e = zipFile.entries();
            ZipEntry entry = null;
            if (e.hasMoreElements()) {
                entry = (ZipEntry) e.nextElement();
            }
            bis = new BufferedInputStream(zipFile.getInputStream(entry));

            dest = new FileOutputStream(sDstFileName);

            data = new byte[nBufferSize];

            writeFully(bis, lLen, dest, nBufferSize, data);
        } catch (IOException e) {
            ioe = e;
            logger.warn(e);
        } finally {
            try {
                if (bis != null) {
                    bis.close();
                }

                if (dest != null) {
                    dest.close();
                }

                if (zipFile != null) {
                    zipFile.close();
                }
            } catch (Exception e) {

            }
        }

        if (ioe != null) {
//unzip file failed, retry to copy the orginal file
            File f = new File(sSrcFileName);
            if (!f.exists()) {
                throw ioe;
            }
            bis = null;
            dest = null;
            RandomAccessFile rafDest = null;
            if (data == null) {
                data = new byte[nBufferSize];
            }
            try {
                bis = new BufferedInputStream(new FileInputStream(f));
                rafDest = new RandomAccessFile(sDstFileName, "rw");
                dest = new FileOutputStream(rafDest.getFD());
                writeFully(bis, lLen, dest, nBufferSize, data);
            } finally {
                try {
                    if (bis != null) {
                        bis.close();
                    }

                    if (dest != null) {
                        dest.close();
                    }

                    if (rafDest != null) {
                        rafDest.close();
                    }
                } catch (Exception e) {

                }
            }

            f = new File(sSrcFileName + ZIP);
            if (f.exists()) {
                f.delete();
            }

        }
    }

    /**
     * conclude whether there are zip file exists
     */
    public static boolean hasZipFile(String sFileName) {
        File f = new File(sFileName + ZIP);
        return f.exists();
    }


    /**
     * unzip file sSrcFileName from lStart into sDstFileName
     *
     * @param sSrcFileName
     * @param lStart
     * @param sDstFileName
     * @throws FileNotFoundException
     * @throws IOException
     */
    public static void unzipFile(String sSrcFileName, long lStart, String sDstFileName) throws FileNotFoundException, IOException {
        int nBufferSize = 4096;

        BufferedInputStream bis = null;
        RandomAccessFile out = null;
        ZipFile zipFile = null;
        try {
            zipFile = new ZipFile(sSrcFileName + ZIP);
            Enumeration e = zipFile.entries();
            ZipEntry entry = null;
            if (e.hasMoreElements()) {
                entry = (ZipEntry) e.nextElement();
            }
            bis = new BufferedInputStream(zipFile.getInputStream(entry));
            bis.skip(lStart);

            out = new RandomAccessFile(sDstFileName, "rw");
            out.seek(lStart);

            byte[] data = new byte[nBufferSize];

            while (true) {
                int nReaded = bis.read(data);
                if (nReaded == -1) {
                    break;
                }

                out.write(data, 0, nReaded);
            }//end while
        } finally {
            try {
                if (out != null) {
                    out.close();
                }

                if (bis != null) {
                    bis.close();
                }

                if (zipFile != null) {
                    zipFile.close();
                }
            } catch (Exception e) {

            }
        }
    }

    public static void backupFile(String sSrcFileName, String tmpExt) throws IOException {
        if (sSrcFileName == null || sSrcFileName.equalsIgnoreCase("")) {
            return;
        }
        String sBakFileNam = sSrcFileName + "." + tmpExt;
        File srcFile = new File(sSrcFileName);
        File bakFile = new File(sBakFileNam);
        if (bakFile.exists()) {
            if (!bakFile.delete()) {
                throw new IOException("Cannot remove old backup file.");
            }
        }
        if (srcFile.exists()) {
            if (!srcFile.renameTo(bakFile)) {
                throw new IOException("Some files are used by other processes.");
            }
            try {
                copyFile(sBakFileNam, sSrcFileName);
            } catch (IOException e) {
                srcFile = new File(sSrcFileName);
                bakFile = new File(sBakFileNam);
                if (srcFile.exists()) {
                    srcFile.delete();
                }
                bakFile.renameTo(srcFile);
                throw e;
            }
        }
    }

    public static void restoreFile(String sSrcFileName, String tmpExt) throws IOException {
        if (sSrcFileName == null || sSrcFileName.equalsIgnoreCase("")) {
            return;
        }
        String sBakFileName = sSrcFileName + "." + tmpExt;
        File srcFile = new File(sSrcFileName);
        File bakFile = new File(sBakFileName);
        if (srcFile.exists()) {
            if (!srcFile.delete()) {
                if (bakFile.exists()) {
                    throw new IOException("Cannot delete the broken file " + sSrcFileName + ", please restore it manually from " + sBakFileName);
                } else {
                    throw new IOException("Cannot delete the broken file " + sSrcFileName + ", please delete it manually.");
                }
            }
        }
        if (bakFile.exists()) {
            if (!bakFile.renameTo(srcFile)) {
                try {
                    copyFile(sBakFileName, sSrcFileName);
                } catch (IOException e) {
                    throw new IOException("Cannot restore " + sSrcFileName + " from " + sBakFileName + ", please restore it manually.");
                }
                bakFile.delete();
            }
        }
    }

    public static void clearBackupFile(String sSrcFileName, String tmpExt) {
        if (sSrcFileName == null || sSrcFileName.equalsIgnoreCase("")) {
            return;
        }
        String sBakFileName = sSrcFileName + "." + tmpExt;
        File bakFile = new File(sBakFileName);
        if (bakFile.exists()) {
            bakFile.delete();
        }
    }

    public static void createFileDir(String zipFile) throws IOException {
        int lastIndex = zipFile.lastIndexOf(FILE_SEPARATOR);
        String fileDirName = zipFile.substring(0, lastIndex);
        new File(fileDirName).mkdirs();
    }
}
TOP

Related Classes of org.chaidb.db.helper.FileUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.