Apache commons.io

Apache Commons IO 提供了一系列用于处理文件、目录、流、过滤和转换的工具方法。本文详细介绍了如何使用 `copyFileToDirectory`、`copyDirectoryToDirectory`、`deleteDirectory` 和 `moveDirectory` 等方法进行文件和目录的复制、删除及移动操作,包括对文件过滤和安全删除的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Create、Modify

1、copyFileToDirectory

/**

     * Copies a file to a directory optionallypreserving the file date.

     * <p>

     * This method copies the contents of thespecified source file

 * toa file of the same name in the specified destination directory.

// destDir必须是文件夹,若不存在则会自动创建

     * The destination directory is created ifit does not exist.

     * If the destination file exists, thenthis method will overwrite it.

    */

    publicstaticvoidcopyFileToDirectory(final File srcFile, final File destDir, finalbooleanpreserveFileDate)

            throws IOException {

        if (destDir == null) {

            thrownew NullPointerException("Destination must not be null");

        }

        if (destDir.exists()&& destDir.isDirectory() == false) {

            thrownew IllegalArgumentException("Destination '" + destDir + "' is not a directory");

        }

        final File destFile = new File(destDir, srcFile.getName());

//java.io.File.File(File parent,String child)

        copyFile(srcFile, destFile, preserveFileDate);

//内部调用下面的copyFile方法

    }

 

/**

     * Copies a file to a new location.

     * <p>

     * This method copies the contents of thespecified source file

     * to the specified destination file.

     * The directory holding the destinationfile is created if it does not exist. // 目标文件父目录不存在则会创建

     * If the destination file exists, thenthis method will overwrite it.

     * // 目标文件存在则会覆盖

     */

    publicstaticvoid copyFile(final File srcFile, final File destFile,

                                finalbooleanpreserveFileDate) throws IOException {

        checkFileRequirements(srcFile, destFile);

        if (srcFile.isDirectory()) {

            thrownew IOException("Source'" + srcFile + "' exists but is a directory");

        }

        if (srcFile.getCanonicalPath().equals(destFile.getCanonicalPath())){

            thrownew IOException("Source'" + srcFile + "' and destination '" + destFile + "' arethe same");

        }

        final File parentFile = destFile.getParentFile();

        if (parentFile != null) {

            if (!parentFile.mkdirs() && !parentFile.isDirectory()){

                thrownew IOException("Destination'" + parentFile + "' directory cannot be created");

            }

        }

        if (destFile.exists() && destFile.canWrite() == false) {

            thrownew IOException("Destination'" + destFile + "' exists but is read-only");

        }

        doCopyFile (srcFile, destFile, preserveFileDate);

// 内部调用doCopyFile方法实现

    }

}

 

/**

     * Internal copy file method.

     * This caches the original file length,and throws an IOException

     * if the output file length is differentfrom the current input file length. // 传输过程中文件改变会抛异常

     * So it may fail if the file changes size.

     * It may also fail with"IllegalArgumentException: Negative size" if the input file istruncated part way

     * through copying the data and the newfile size is less than the current position.

     */

    privatestaticvoid doCopyFile(final File srcFile, final File destFile, finalbooleanpreserveFileDate)

            throws IOException {

        if (destFile.exists() && destFile.isDirectory()){

            thrownew IOException("Destination'" + destFile + "' exists but is a directory");

        }

 

        try (FileInputStream fis = new FileInputStream(srcFile);

             FileChannel input = fis.getChannel();

// 内部调用NIO channel

             FileOutputStream fos = new FileOutputStream(destFile);

             FileChannel output = fos.getChannel()) {

            finallongsize = input.size(); // TODO See IO-386

            longpos = 0;

            longcount = 0;

            while (pos < size) {

                finallongremain = size - pos;

                count = remain > FILE_COPY_BUFFER_SIZE ? FILE_COPY_BUFFER_SIZE : remain;

                finallongbytesCopied = output.transferFrom(input, pos, count);

                if (bytesCopied == 0) { // IO-385 -can happen if file is truncated after caching the size

                    break; // ensure we don't loop forever

                }

                pos += bytesCopied;

            }

        }

 

        finallongsrcLen = srcFile.length(); // TODO See IO-386

        finallongdstLen = destFile.length(); // TODO See IO-386

        if (srcLen != dstLen) {

            thrownew IOException("Failedto copy full contents from '" +

                    srcFile + "' to '" + destFile + "'Expected length: " + srcLen + " Actual: " + dstLen);

        }

        if (preserveFileDate) {

            destFile.setLastModified(srcFile.lastModified());

        }

    }

2、copyDirectoryToDirectory

/**

     * Copies a directory to within anotherdirectory preserving the file dates.

     * <p>

     * This method copies the source directoryand all its contents to a

     * directory of the same name in thespecified destination directory.

     * <p>

     * The destination directory is created if it does notexist.

     * If the destination directory did exist,then this method merges

     * the source with the destination, withthe source taking precedence.

      */

//默认不过滤文件

    publicstaticvoidcopyDirectoryToDirectory(final File srcDir, final File destDir) throws IOException {

        if (srcDir == null) {

            thrownew NullPointerException("Source must not be null");

        }

        if (srcDir.exists() && srcDir.isDirectory()== false) {

            thrownew IllegalArgumentException("Source '" + destDir + "' is not a directory");

        }

        if (destDir == null) {

            thrownew NullPointerException("Destination must not be null");

        }

        if (destDir.exists() && destDir.isDirectory()== false) {

            thrownew IllegalArgumentException("Destination '" + destDir + "' is not a directory");

        }

        copyDirectory(srcDir, new File(destDir, srcDir.getName()), true);

    }

 

/**

     * Copies a filtered directory to a newlocation.

     * <p>

     * This method copies the contents of thespecified source directory

     * to within the specified destinationdirectory.

     * <p>

     * The destination directory is created ifit does not exist.

     * If the destination directory did exist,then this method merges

     * the source with the destination, withthe source taking precedence.

     * <p>

     * <strong>Note:</strong> Setting <code>preserveFileDate</code> to

     * {@code true} tries to preserve thefiles' last modified

     * date/times using {@link File#setLastModified(long)}, however it is

     * not guaranteed that those operationswill succeed.

     * If the modification operation fails, noindication is provided.

     * </p>

     * <h3>Example: Copy directories only</h3>

     * <pre>

     * // only copy the directory structure

     * FileUtils.copyDirectory(srcDir, destDir, DirectoryFileFilter.DIRECTORY,false);

     </pre>

     *

     * <h3>Example: Copy directories and txt files</h3>

     * <pre>

     * // Create a filter for ".txt" files

     * IOFileFilter txtSuffixFilter =FileFilterUtils.suffixFileFilter(".txt");

     * IOFileFilter txtFiles =FileFilterUtils.andFileFilter(FileFileFilter.FILE, txtSuffixFilter);

     *

     * // Create a filter for either directories or ".txt" files

     * FileFilter filter =FileFilterUtils.orFileFilter(DirectoryFileFilter.DIRECTORY, txtFiles);

     *

     * // Copy using the filter

     * FileUtils.copyDirectory(srcDir, destDir, filter, false);

     </pre>

     **/

    publicstaticvoid copyDirectory(final File srcDir, final File destDir,

                                     final FileFilter filter, finalbooleanpreserveFileDate) throws IOException {

        checkFileRequirements(srcDir, destDir);

        if (!srcDir.isDirectory()) {

            thrownew IOException("Source'" + srcDir + "' exists but is not a directory");

        }

        if (srcDir.getCanonicalPath().equals(destDir.getCanonicalPath())){

            thrownew IOException("Source'" + srcDir + "' and destination '" + destDir + "' arethe same");

        }

 

        // Cater for destination being directorywithin the source directory (see IO-141)

        List<String> exclusionList = null;

        if (destDir.getCanonicalPath().startsWith(srcDir.getCanonicalPath())) {

            final File[] srcFiles = filter == null ? srcDir.listFiles() : srcDir.listFiles(filter);  //文件如何过滤的

            if (srcFiles != null && srcFiles.length > 0) {

                exclusionList = new ArrayList<>(srcFiles.length);

                for (final File srcFile : srcFiles) {

                    final File copiedFile = new File(destDir, srcFile.getName());

                    exclusionList.add(copiedFile.getCanonicalPath());

                }

            }

        }

        doCopyDirectory(srcDir, destDir, filter, preserveFileDate, exclusionList);

    }

 

/**

     * Internal copy directory method

     */

    privatestaticvoid doCopyDirectory(final File srcDir, final File destDir, final FileFilter filter,

                                        finalbooleanpreserveFileDate, final List<String> exclusionList)

            throws IOException {

        // recurse

        final File[] srcFiles = filter == null ? srcDir.listFiles() : srcDir.listFiles(filter);

        if (srcFiles == null) { // null ifabstract pathname does not denote a directory, or if an I/O error occurs

            thrownew IOException("Failedto list contents of " + srcDir);

        }

        if (destDir.exists()) {

            if (destDir.isDirectory() == false) {

                thrownew IOException("Destination'" + destDir + "' exists but is not a directory");

            }

        } else {

            if (!destDir.mkdirs() && !destDir.isDirectory()){

                thrownew IOException("Destination'" + destDir + "' directory cannot be created");

            }

        }

        if (destDir.canWrite() == false) {

            thrownew IOException("Destination'" + destDir + "' cannot be written to");

        }

        for (final File srcFile : srcFiles) {

            final File dstFile = new File(destDir, srcFile.getName());

            if (exclusionList == null || !exclusionList.contains(srcFile.getCanonicalPath())) {

                if (srcFile.isDirectory()) {

                    doCopyDirectory(srcFile, dstFile, filter, preserveFileDate, exclusionList);  //文件夹则递归

                } else {

                    doCopyFile(srcFile, dstFile, preserveFileDate); //文件则copy

                }

            }

        }

 

        // Do this last, as the above has probablyaffected directory metadata

        if (preserveFileDate) {

            destDir.setLastModified(srcDir.lastModified());

        }

    }

3、copyToDirectory

内部调用copyFileToDirectory或者copyDirectoryToDirectory

即不需要判断src file是文件还是文件夹了

publicstaticvoid copyToDirectory(final File src, final File destDir) throws IOException {

        if (src == null) {

            thrownew NullPointerException("Source must not be null");

        }

        if (src.isFile()) {

            copyFileToDirectory(src, destDir);

        } elseif (src.isDirectory()) {

            copyDirectoryToDirectory (src, destDir);

        } else {

            thrownew IOException("Thesource " + src + " does not exist");

        }

    }

二、Delete

1、deleteDirectory

/**

     * Deletes a directory recursively.递归删除

       */

    publicstaticvoid deleteDirectory(final File directory) throws IOException {

        if (!directory.exists()) {

            return;

        }

 

        if (!isSymlink(directory)) {

            cleanDirectory(directory);

        }

 

        if (!directory.delete()) {

            final String message =

                    "Unable to delete directory " + directory + ".";

            thrownew IOException(message);

        }

    }

2、deleteQuietly

/**

     * Deletes a file, never throwing an exception. If file is a directory, delete it andall sub-directories.

     */

    publicstaticboolean deleteQuietly(final File file) {

        if (file == null) {

            returnfalse;

        }

        try {

            if (file.isDirectory()) {

                cleanDirectory(file);  //内部调用cleanDirectory,先清空文件夹

            }

        } catch (final Exception ignored) {

        }

 

        try {

            returnfile.delete();  //再去删除

        } catch (final Exception ignored) {

            returnfalse;

        }

    }

 

/**

     * Cleans a directory without deleting it.

把文件夹清空,但是不删除这个文件夹

        */

    publicstaticvoid cleanDirectory(final File directory) throws IOException {

        final File[] files = verifiedListFiles(directory);

 

        IOException exception = null;

        for (final File file : files) {

            try {

                forceDelete(file);

            } catch (final IOException ioe) {

                exception = ioe;

            }

        }

 

        if (null != exception) {

            throwexception;

        }

    }

/**

     * Lists files in a directory, assertingthat the supplied directory satisfies exists and is a directory

     */

    privatestatic File[] verifiedListFiles(final File directory) throws IOException {

        if (!directory.exists()) {

            final String message = directory + " doesnot exist";

            thrownew IllegalArgumentException(message);

        }

 

        if (!directory.isDirectory()) {

            final String message = directory + " is nota directory";

            thrownew IllegalArgumentException(message);

        }

 

        final File[] files = directory.listFiles();

        if (files == null) { // null ifsecurity restricted

            thrownew IOException("Failedto list contents of " + directory);

        }

        returnfiles;

    }

 

/**

     * Deletes a file. If file is a directory, deleteit and all sub-directories.

      */

    publicstaticvoid forceDelete(final File file) throws IOException {

        if (file.isDirectory()) {

            deleteDirectory(file);

        } else {

            finalbooleanfilePresent = file.exists();

            if (!file.delete()) {

                if (!filePresent) {

                    thrownew FileNotFoundException("File does not exist: " + file);

                }

                final String message =

                        "Unable to delete file:" + file;

                thrownew IOException(message);

            }

        }

    }

三、Move,rename

1、moveDirectory

目标目录必须存在,不然抛异常,不会自动创建,要自动创建的,可用moveDirectoryToDirectory

/**

     * Moves a directory.

     * <p>

     * When the destination directory is onanother file system, do a "copy and delete".

     */

    publicstaticvoid moveDirectory(final File srcDir, final File destDir) throws IOException {

        if (srcDir == null) {

            thrownew NullPointerException("Source must not be null");

        }

        if (destDir == null) {

            thrownew NullPointerException("Destination must not be null");

        }

        if (!srcDir.exists()) {

            thrownew FileNotFoundException("Source '" + srcDir + "' does not exist");

        }

        if (!srcDir.isDirectory()) {

            thrownew IOException("Source'" + srcDir + "' is not a directory");

        }

        if (destDir.exists()) {

            thrownew FileExistsException("Destination '" + destDir + "' already exists");

        }

先尝试rename,如果rename成功,说明是rename

        finalbooleanrename = srcDir.renameTo(destDir);

        if (!rename) {

            if (destDir.getCanonicalPath().startsWith(srcDir.getCanonicalPath() + File.separator)) {

                thrownew IOException("Cannotmove directory: " + srcDir + " to a subdirectory of itself: " + destDir);

            }

如果rename失败,也是土办法,赋值原来的到新地方,再删除原来的,

            copyDirectory(srcDir, destDir);

            deleteDirectory(srcDir);

            if (srcDir.exists()) {

                thrownew IOException("Failedto delete original directory '" + srcDir +

                        "' after copy to '" + destDir + "'");

            }

        }

}

 

2、moveFile(final FilesrcFile, final File destFile)

与上同理,也是先尝试rename,不行再copy删除

目标目录必须存在,不然抛异常,不会自动创建,要自动创建的,可用moveFileToDirectory

有更方便的,moveToDirectory,无需自己判断是移动文件还是文件夹

3、moveToDirectory

moveToDirectory (final File src, final File destDir,final boolean createDestDir)

 

 

四、文件过滤

1、java.io.FileFilter 

 

2、java.io.FilenameFilter

3、Apache Commons filefilter

该包实现了上述两个接口

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值