对文件的操作

package com.saicfc.saicifx3.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.RandomAccessFile;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import org.apache.commons.compress.archivers.ArchiveException;
import org.apache.commons.compress.archivers.ArchiveStreamFactory;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.saicfc.saicifx3.vo.FileInfo;

/**
 * 文件辅助类
 * 
 * @author ShenHuaJie
 * @since 2012-03-22
 */
public class FileUtils {
    private static Log    log      = LogFactory.getLog(FileUtils.class);
    private static int    BUF      = 1024;
    private static String encoding = "GBK";

    /**
     * 单个文件拷贝。
     * 
     * @param srcFile
     * @param destFile
     * @param overwrite
     *            是否覆盖目的文件
     * @throws IOException
     */
    public static void copyFile(File srcFile, File destFile, boolean overwrite) throws IOException {

        // 首先判断源文件是否存在
        if (!srcFile.exists()) {
            throw new FileNotFoundException("Cannot find the source file: "
                                            + srcFile.getAbsolutePath());
        }
        // 判断源文件是否可读
        if (!srcFile.canRead()) {
            throw new IOException("Cannot read the source file: " + srcFile.getAbsolutePath());
        }

        if (overwrite == false) {
            // 目标文件存在就不覆盖
            if (destFile.exists())
                return;
        } else {
            // 如果要覆盖已经存在的目标文件,首先判断是否目标文件可写。
            if (destFile.exists()) {
                if (!destFile.canWrite()) {
                    throw new IOException("Cannot write the destination file: "
                                          + destFile.getAbsolutePath());
                }
            } else {
                // 不存在就创建一个新的空文件。
                if (!destFile.createNewFile()) {
                    throw new IOException("Cannot write the destination file: "
                                          + destFile.getAbsolutePath());
                }
            }
        }

        BufferedInputStream inputStream = null;
        BufferedOutputStream outputStream = null;
        byte[] block = new byte[1024];
        try {
            inputStream = new BufferedInputStream(new FileInputStream(srcFile));
            outputStream = new BufferedOutputStream(new FileOutputStream(destFile));
            while (true) {
                int readLength = inputStream.read(block);
                if (readLength == -1)
                    break;// end of file
                outputStream.write(block, 0, readLength);
            }
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException ex) {
                    // just ignore
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException ex) {
                    // just ignore
                }
            }
        }
    }

    /**
     * 单个文件拷贝。
     * 
     * @param srcFilename
     * @param destFilename
     * @param overwrite
     * @throws IOException
     */
    public static void copyFile(String srcFilename, String destFilename, boolean overwrite)
                                                                                           throws IOException {

        File srcFile = new File(srcFilename);
        // 首先判断源文件是否存在
        if (!srcFile.exists()) {
            throw new FileNotFoundException("Cannot find the source file: "
                                            + srcFile.getAbsolutePath());
        }
        // 判断源文件是否可读
        if (!srcFile.canRead()) {
            throw new IOException("Cannot read the source file: " + srcFile.getAbsolutePath());
        }

        File destFile = new File(destFilename);

        if (overwrite == false) {
            // 目标文件存在就不覆盖
            if (destFile.exists())
                return;
        } else {
            // 如果要覆盖已经存在的目标文件,首先判断是否目标文件可写。
            if (destFile.exists()) {
                if (!destFile.canWrite()) {
                    throw new IOException("Cannot write the destination file: "
                                          + destFile.getAbsolutePath());
                }
            } else {
                // 不存在就创建一个新的空文件。
                if (!destFile.createNewFile()) {
                    throw new IOException("Cannot write the destination file: "
                                          + destFile.getAbsolutePath());
                }
            }
        }

        BufferedInputStream inputStream = null;
        BufferedOutputStream outputStream = null;
        byte[] block = new byte[1024];
        try {
            inputStream = new BufferedInputStream(new FileInputStream(srcFile));
            outputStream = new BufferedOutputStream(new FileOutputStream(destFile));
            while (true) {
                int readLength = inputStream.read(block);
                if (readLength == -1)
                    break;// end of file
                outputStream.write(block, 0, readLength);
            }
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException ex) {
                    // just ignore
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException ex) {
                    // just ignore
                }
            }
        }
    }

    /**
     * 拷贝文件,从源文件夹拷贝文件到目的文件夹。 <br>
     * 参数源文件夹和目的文件夹,最后都不要带文件路径符号,例如:c:/aa正确,c:/aa/错误。
     * 
     * @param srcDirName
     *            源文件夹名称 ,例如:c:/test/aa 或者c:\\test\\aa
     * @param destDirName
     *            目的文件夹名称,例如:c:/test/aa 或者c:\\test\\aa
     * @param overwrite
     *            是否覆盖目的文件夹下面的文件。
     * @throws IOException
     */
    public static void copyFiles(String srcDirName, String destDirName, boolean overwrite)
                                                                                          throws IOException {
        File srcDir = new File(srcDirName);// 声明源文件夹
        // 首先判断源文件夹是否存在
        if (!srcDir.exists()) {
            throw new FileNotFoundException("Cannot find the source directory: "
                                            + srcDir.getAbsolutePath());
        }

        File destDir = new File(destDirName);
        if (overwrite == false) {
            if (destDir.exists()) {
                // do nothing
            } else {
                if (destDir.mkdirs() == false) {
                    throw new IOException("Cannot create the destination directories = " + destDir);
                }
            }
        } else {
            // 覆盖存在的目的文件夹
            if (destDir.exists()) {
                // do nothing
            } else {
                // create a new directory
                if (destDir.mkdirs() == false) {
                    throw new IOException("Cannot create the destination directories = " + destDir);
                }
            }
        }

        // 循环查找源文件夹目录下面的文件(屏蔽子文件夹),然后将其拷贝到指定的目的文件夹下面。
        File[] srcFiles = srcDir.listFiles();
        if (srcFiles == null || srcFiles.length < 1) {
            // throw new IOException ("Cannot find any file from source
            // directory!!!");
            return;// do nothing
        }

        // 开始复制文件
        int SRCLEN = srcFiles.length;

        for (int i = 0; i < SRCLEN; i++) {
            // File tempSrcFile = srcFiles[i];

            File destFile = new File(destDirName + File.separator + srcFiles[i].getName());
            // 注意构造文件对象时候,文件名字符串中不能包含文件路径分隔符";".
            // log.debug(destFile);
            if (srcFiles[i].isFile()) {
                copyFile(srcFiles[i], destFile, overwrite);
            } else {
                // 在这里进行递归调用,就可以实现子文件夹的拷贝
                copyFiles(srcFiles[i].getAbsolutePath(),
                    destDirName + File.separator + srcFiles[i].getName(), overwrite);
            }
        }
    }

    /**
     * 创建单个文件夹。
     * 
     * @param dir
     * @param ignoreIfExitst
     *            true 表示如果文件夹存在就不再创建了。false是重新创建。
     * @throws IOException
     */
    public static void createDir(String dir, boolean ignoreIfExitst) throws IOException {
        File file = new File(dir);
        if (ignoreIfExitst && file.exists()) {
            return;
        }
        if (file.mkdir() == false) {
            throw new IOException("Cannot create the directory = " + dir);
        }
    }

    /**
     * 创建多个文件夹
     * 
     * @param dir
     * @param ignoreIfExitst
     * @throws IOException
     */
    public static void createDirs(String dir, boolean ignoreIfExitst) throws IOException {
        File file = new File(dir);

        if (ignoreIfExitst && file.exists()) {
            return;
        }
        if (file.mkdirs() == false) {
            throw new IOException("Cannot create directories = " + dir);
        }
    }

    /**
     * 删除文件夹及其下面的子文件夹
     * 
     * @param dir
     * @throws IOException
     */
    public static void deleteDir(File dir) throws IOException {
        if (dir.isFile())
            throw new IOException("IOException -> BadInputException: not a directory.");
        File[] files = dir.listFiles();
        if (files != null) {
            for (int i = 0; i < files.length; i++) {
                File file = files[i];
                if (file.isFile()) {
                    file.delete();
                } else {
                    deleteDir(file);
                }
            }
        }// if
        dir.delete();
    }

    /**
     * 删除一个文件。
     * 
     * @param filename
     * @throws IOException
     */
    public static void deleteFile(String filename) throws IOException {
        File file = new File(filename);
        log.trace("Delete file = " + filename);
        if (file.isDirectory()) {
            throw new IOException("IOException -> BadInputException: not a file.");
        }
        if (file.exists() == false) {
            throw new IOException("IOException -> BadInputException: file is not exist.");
        }
        if (file.delete() == false) {
            throw new IOException("Cannot delete file. filename = " + filename);
        }
    }

    /**
     * 解压缩
     * 
     * @param srcPath
     * @param toPath
     * @throws IOException
     * @throws ArchiveException
     */
    public static void doUnZip(String srcPath, String toPath) throws IOException, ArchiveException {
        ZipFile file = new ZipFile(srcPath, encoding);
        Enumeration<ZipArchiveEntry> en = file.getEntries();
        ZipArchiveEntry ze;
        while (en.hasMoreElements()) {
            ze = en.nextElement();
            File f = new File(toPath, ze.getName());// 创建完整路径
            if (ze.isDirectory()) {
                f.mkdirs();
                continue;
            } else
                f.getParentFile().mkdirs();

            InputStream is = file.getInputStream(ze);
            OutputStream os = new FileOutputStream(f);
            IOUtils.copy(is, os, BUF);
            is.close();
            os.close();
        }
        file.close();
    }

    /**
     * 压缩文件或文件夹
     * 
     * @param files
     * @param toPath
     * @throws ArchiveException
     * @throws IOException
     */
    public static void doZip(List<File> files, String toPath) throws ArchiveException, IOException {
        // or new ZipArchiveOutputStream(new FileOutputStream(path))
        ZipArchiveOutputStream zos = (ZipArchiveOutputStream) new ArchiveStreamFactory()
            .createArchiveOutputStream("zip", new FileOutputStream(toPath));
        zos.setEncoding(encoding);

        ZipArchiveEntry ze;
        for (File file : files) {
            if (!file.exists())
                continue;
            ze = new ZipArchiveEntry(getEntryName(file, null));// 获取每个文件相对路径,作为在ZIP中路径
            zos.putArchiveEntry(ze);
            // folder
            if (ze.isDirectory()) {
                zos.closeArchiveEntry();
                continue;
            }
            // file
            FileInputStream fis = new FileInputStream(file);
            IOUtils.copy(fis, zos, BUF);
            fis.close();
            zos.closeArchiveEntry();
        }
        zos.close();
    }

    /**
     * 将文件清空。
     * 
     * @param srcFilename
     * @throws IOException
     */
    public static void emptyFile(String srcFilename) throws IOException {
        File srcFile = new File(srcFilename);
        if (!srcFile.exists()) {
            throw new FileNotFoundException("Cannot find the file: " + srcFile.getAbsolutePath());
        }
        if (!srcFile.canWrite()) {
            throw new IOException("Cannot write the file: " + srcFile.getAbsolutePath());
        }

        FileOutputStream outputStream = new FileOutputStream(srcFilename);
        outputStream.close();
    }

    /**
     * 获取到目录下面文件的大小。包含了子目录。
     * 
     * @param dir
     * @return
     * @throws IOException
     */
    public static long getDirLength(File dir) throws IOException {
        if (dir.isFile())
            throw new IOException("BadInputException: not a directory.");
        long size = 0;
        File[] files = dir.listFiles();
        if (files != null) {
            for (int i = 0; i < files.length; i++) {
                File file = files[i];
                // file.getName();
                // System.out.println(file.getName());
                long length = 0;
                if (file.isFile()) {
                    length = file.length();
                } else {
                    length = getDirLength(file);
                }
                size += length;
            }// for
        }// if
        return size;
    }

    /**
     * 以行为单位读取文件,读取行数记录
     * 
     * @param fileName
     * @return
     * @throws IOException
     */
    public static int getFileLineNumber(String fileName) throws IOException {
        File file = new File(fileName);
        BufferedReader reader = null;
        int line = 0;
        try {
            reader = new BufferedReader(new FileReader(file));
            // 一次读入一行,直到读入null为文件结束
            while (reader.readLine() != null) {
                line++;// 显示行号
            }
        } finally {
            if (reader != null) {
                reader.close();
            }
        }
        return line;
    }

    /**
     * 列出指定文件目录下面的文件信息。
     * 
     * @param dir
     * @return
     * @throws IOException
     */
    public static List<FileInfo> getFiles(File dir) throws IOException {
        if (dir.isFile())
            throw new IOException("BadInputException: not a directory.");
        if (!dir.exists()) {
            throw new IOException(" don't exist ");
        }

        File[] files = dir.listFiles();
        int LEN = 0;
        if (files != null) {
            LEN = files.length;
        }
        List<FileInfo> l = new ArrayList<FileInfo>();
        long tempFLen = 0; // 文件长度
        for (int i = 0; i < LEN; i++) {
            FileInfo temp = new FileInfo();
            temp.setFileName(files[i].getName());
            temp.setIsDir(files[i].isDirectory());
            // 是文件,且包含.
            if (files[i].isFile()) {
                if (files[i].getName().lastIndexOf(".") != -1)
                    temp.setFileType(files[i].getName().substring(
                        files[i].getName().lastIndexOf(".")));
            } else {
                temp.setFileType("文件夹");
            }
            tempFLen = files[i].length();
            temp.setFileLength(tempFLen);
            if (tempFLen / 1024 / 1024 / 1024 > 0) {
                temp.setFileSize(files[i].length() / 1024 / 1024 / 1024 + "G");
            } else if (tempFLen / 1024 / 1024 > 0) {
                temp.setFileSize(files[i].length() / 1024 / 1024 + "M");
            } else if (tempFLen / 1024 > 0) {
                temp.setFileSize(files[i].length() / 1024 + "K");
            } else {
                temp.setFileSize(tempFLen + "byte");
            }
            temp.setFilePath(files[i].getAbsolutePath().replaceAll("[\\\\]", "/"));
            temp.setLastModified(DateUtil.getDateFromLong(files[i].lastModified()));
            temp.setIsHidden(files[i].isHidden());
            temp.setAuthor(null);
            temp.setVersion(null);
            temp.setFileClass(null);
            temp.setRemark(null);
            l.add(temp);
        }
        return l;
    }

    public static String getFileSeparator() {
        return java.io.File.separator;
    }

    /*
     * 1 ABC 2 abC Gia su doc tu dong 1 lay ca thay 5 dong => 1 --> 5 3 ABC
     */
    public static String[] getLastLines(File file, int linesToReturn) throws IOException,
                                                                     FileNotFoundException {

        final int AVERAGE_CHARS_PER_LINE = 250;
        final int BYTES_PER_CHAR = 2;

        RandomAccessFile randomAccessFile = null;
        StringBuffer buffer = new StringBuffer(linesToReturn * AVERAGE_CHARS_PER_LINE);
        int lineTotal = 0;
        try {
            randomAccessFile = new RandomAccessFile(file, "r");
            long byteTotal = randomAccessFile.length();
            long byteEstimateToRead = linesToReturn * AVERAGE_CHARS_PER_LINE * BYTES_PER_CHAR;

            long offset = byteTotal - byteEstimateToRead;
            if (offset < 0) {
                offset = 0;
            }

            randomAccessFile.seek(offset);
            // log.debug("SKIP IS ::" + offset);

            String line = null;
            String lineUTF8 = null;
            while ((line = randomAccessFile.readLine()) != null) {
                lineUTF8 = new String(line.getBytes("ISO8859_1"), "UTF-8");
                lineTotal++;
                buffer.append(lineUTF8).append("\n");
            }
        } finally {
            if (randomAccessFile != null) {
                try {
                    randomAccessFile.close();
                } catch (IOException ex) {
                }
            }
        }

        String[] resultLines = new String[linesToReturn];
        BufferedReader in = null;
        try {
            in = new BufferedReader(new StringReader(buffer.toString()));

            int start = lineTotal /* + 2 */- linesToReturn; // Ex : 55 - 10 = 45
            // ~ offset
            if (start < 0)
                start = 0; // not start line
            for (int i = 0; i < start; i++) {
                in.readLine(); // loop until the offset. Ex: loop 0, 1 ~~ 2
                // lines
            }

            int i = 0;
            String line = null;
            while ((line = in.readLine()) != null) {
                resultLines[i] = line;
                i++;
            }
        } catch (IOException ie) {
            log.error("Error" + ie);
            throw ie;
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException ex) {
                }
            }
        }
        return resultLines;
    }

    public static String getPathSeparator() {
        return java.io.File.pathSeparator;
    }

    /**
     * 读取文件的内容,并将文件内容以字符串的形式返回。
     * 
     * @param fileName
     * @param srcEncoding
     * @return
     * @throws FileNotFoundException
     * @throws IOException
     */
    public static String readFile(String fileName, String srcEncoding)
                                                                      throws FileNotFoundException,
                                                                      IOException {
        File file = null;
        try {
            file = new File(fileName);
            if (file.isFile() == false) {
                throw new IOException("'" + fileName + "' is not a file.");
            }
        } finally {
            // we dont have to close File here
        }

        BufferedReader reader = null;
        try {
            StringBuffer result = new StringBuffer(1024);
            FileInputStream fis = new FileInputStream(fileName);
            reader = new BufferedReader(new InputStreamReader(fis, srcEncoding));

            char[] block = new char[512];
            while (true) {
                int readLength = reader.read(block);
                if (readLength == -1)
                    break;// end of file
                result.append(block, 0, readLength);
            }
            return result.toString();
        } catch (FileNotFoundException fe) {
            log.error("Error", fe);
            throw fe;
        } catch (IOException e) {
            log.error("Error", e);
            throw e;
        } finally {
            try {
                if (reader != null)
                    reader.close();
            } catch (IOException ex) {
            }
        }
    }

    /**
     * Write content to a fileName with the destEncoding 写文件。如果此文件不存在就创建一个。
     * 
     * @param content
     *            String
     * @param fileName
     *            String
     * @param destEncoding
     *            String
     * @throws FileNotFoundException
     * @throws IOException
     */
    public static void writeFile(String content, String fileName, String destEncoding)
                                                                                      throws FileNotFoundException,
                                                                                      IOException {
        File file = null;
        try {
            file = new File(fileName);
            if (!file.exists()) {
                if (file.createNewFile() == false) {
                    throw new IOException("create file '" + fileName + "' failure.");
                }
            }
            if (file.isFile() == false) {
                throw new IOException("'" + fileName + "' is not a file.");
            }
            if (file.canWrite() == false) {
                throw new IOException("'" + fileName + "' is a read-only file.");
            }
        } finally {
            // we dont have to close File here
        }

        BufferedWriter out = null;
        try {
            FileOutputStream fos = new FileOutputStream(fileName);
            out = new BufferedWriter(new OutputStreamWriter(fos, destEncoding));

            out.write(content);
            out.flush();
        } catch (FileNotFoundException fe) {
            log.error("Error", fe);
            throw fe;
        } catch (IOException e) {
            log.error("Error", e);
            throw e;
        } finally {
            try {
                if (out != null)
                    out.close();
            } catch (IOException ex) {
            }
        }
    }

    private static String getEntryName(File file, String rootPath) {
        String entryName;
        String fPath = file.getAbsolutePath();
        if (fPath.indexOf(rootPath) != -1)
            entryName = fPath.substring(rootPath.length() + 1);
        else
            entryName = file.getName();
        if (file.isDirectory())
            entryName += "/";// "/"后缀表示entry是文件夹
        return entryName;
    }
}

你可能感兴趣的:(文件)