Java拷贝文件(保留文件名大小写、文件名增加时间戳)、递归删除文件、压缩文件

1,拷贝文件

拷贝文件首先要判断原文件是否存在,若不存在则失败;然后使用Files.copy复制文件,如果其父目录不存在存在,会出现java.nio.file.NoSuchFileException异常,如下图所示:
在这里插入图片描述
则需要先判断父母录是否存在,若不存在需要先创建父目录。实现代码如下所示:(其传参均为绝对路径,即带文件名。

	public static boolean copyFile(String oldPath, String newPath) {
        try {
            File file = new File(oldPath);
            if (!file.exists()) {
                return false;
            }
            File newFile = new File(newPath);
            if (!newFile.getParentFile().exists()) {
                //创建上级目录
                newFile.getParentFile().mkdirs();
            }

            Files.copy((new File(oldPath)).toPath(), new FileOutputStream(newPath));

        } catch (IOException ioException) {
            ioException.printStackTrace();
            return false;
        }
        return true;
    }

若新路径只想传所拷贝的路径,不带文件名,则实现方式如下所示:
可用StandardCopyOption指的拷贝类型:REPLACE_EXISTING(存在替换)、COPY_ATTRIBUTES(拷贝属性)、ATOMIC_MOVE(移动操作)。

    public static boolean copyFile(String oldPath, String newPath) {
        try {
            File file = new File(oldPath);
            if (!file.exists()) {
                return false;
            }
            String fileName = file.getName();
            newPath = newPath + fileName;
            File newFile = new File(newPath);
            if (!newFile.getParentFile().exists()) {
                //创建上级目录
                newFile.getParentFile().mkdirs();
            }

            Files.copy((new File(oldPath)).toPath(), (new File(newPath)).toPath(), StandardCopyOption.REPLACE_EXISTING);
        } catch (IOException ioException) {
            ioException.printStackTrace();
            return false;
        }
        return true;
    }

2, 文件名大小写问题

由于windows系统对文件名的大小写问题不敏感,不区分文件名大小写,即在windows系统某个路径下不能同时存在文件名为HELLO.txt 和文件名为hello.txt的两个文件。
则由上面实现代码来拷贝文件的话则会改变复制后的文件名,如想要把源路径D:\Test\下的testCsv.csv文件拷贝到D:\Test\test2\目录下,但是所传递的参数所带文件名都是TESTCSV.csv,其能够在原路径中找到文件,也能实现拷贝操作,但是拷贝后的文件名是TESTCSV.csv。

解决方法:
通过file.getCanonicalFile().getName()去获取原路径的真实名称,获取到的是本地目录下真实大小写的文件名,其实现代码如下所示:

    public static boolean copyFile(String oldPath, String newPath) {
        try {
            File file = new File(oldPath);
            if (!file.exists()) {
                return false;
            }
            // String fileName = file.getName();
            String fileName = file.getCanonicalFile().getName();
            newPath = newPath + fileName;
            File newFile = new File(newPath);
            if (!newFile.getParentFile().exists()) {
                //创建上级目录
                newFile.getParentFile().mkdirs();
            }

            Files.copy((new File(oldPath)).toPath(), (new File(newPath)).toPath(), StandardCopyOption.REPLACE_EXISTING);
        } catch (IOException ioException) {
            ioException.printStackTrace();
            return false;
        }
        return true;
    }

3,文件名增加时间戳

    public static boolean copyFile(String oldPath, String newPath) {
        try {
            File file = new File(oldPath);
            if (!file.exists()) {
                return false;
            }
            // String fileName = file.getName();
            String fileName = file.getCanonicalFile().getName();
            // 给文件名后追加时间戳
            if(fileName.lastIndexOf(".")==-1){
            	// 考虑没有文件名后缀的情况
				fileName = fileName + "_" + new SimpleDateFormat("yyyyMMDDHHmmss".format(new Date());
			} else {
				fileName = fileName.substring(0, fileName.lastIndexOf(".")) + "_" + 
				new SimpleDateFormat("yyyyMMDDHHmmss".format(new Date()) + 
				fileName.substring(fileName.lastIndexOf("."));
			}
            newPath = newPath + fileName;
            File newFile = new File(newPath);
            if (!newFile.getParentFile().exists()) {
                //创建上级目录
                newFile.getParentFile().mkdirs();
            }

            Files.copy((new File(oldPath)).toPath(), (new File(newPath)).toPath(), StandardCopyOption.REPLACE_EXISTING);
        } catch (IOException ioException) {
            ioException.printStackTrace();
            return false;
        }
        return true;
    }

4,删除文件夹

若存在需求需要删除某个文件夹下10天之前的所有文件及文件夹(只保留7天之内的),如一般日志所放的文件夹一般需要给予一定的时间进行清理。Java删除文件夹,若该文件夹下有文件,这不能将这个文件夹删除,及需要将文件夹下的所有文件删除才能将此文件夹删除。

	/**
	*	删除文件或文件夹及文件夹下的所有文件 (递归删除文件夹,若文件被占用则不能被删除,直接跳过)
	*
	*	@param file 文件对象
	*	@return 删除文件是否成功
	*/
	public static boolean deleteDirFile (File file) {
		if(file.isDirectory()) {
			File[] files = file.listFiles();
			if(files == null) {
				return file.delete();
			}
			for(File fi : files) {
				deleteDirFile(fi);
			}
		}
		return file.delete();
	}
	
	// 清空文件夹下day天以前的文件
	public static boolean deleteTimeOutDir(String dirPath, long day) {
		File file = new File(dirPath);
		if(!file.exist()) {
			System.out.println("this dirPath does not exist.");
			return true;
		}
		if(!file.isDirectory()) {
			System.out.println("this dirPath is not a directory.");
			return false;
		}
		// 得到目录下的所有文件及文件夹
		File[] files = file.listFiles();
		if(files == null) {
			System.out.println("no other files exist in this directory.");
			return true;
		}
		// 获取当前时间 
		long currentTime = System.currentTimeMillis();
		// 文件保留的时间差  day为int时,此处day需强转,否则得到的是负数(溢出)
		long dayTime = day * (24 * 60 * 60 * 1000);
		
		for(File f : files) {
			// 得到文件或文件夹的绝对路径
			File absFile = f.getAbsoluteFile();
		
			System.out.println(absFile);
			// 文件的最近修改时间
			System.out.println(f.getName() + "   最近修改时间:" + f.lastModified() + "    最近修改时间:" + absFile.lastModified() );   
			
			// 根据文件的绝对路径获取path
			Path path = Paths.get(absFile.getAbsolutePath());
			// 根据path获取文件的基本属性类
			BasicFileAttributes attributes;
			try {
				attributes = File.readAttributes(path, BasicFileAttributes.class);
			} catch (IOException exception) {
				System.out.println("get file attributes error: " + exception);
				return false;
			}
			// 从基本属性中获取文件创建时间
			FileTime fileTime = attributes.creationTime();
			// 将时间转换为毫秒
			long millis = fileTime.toMillis();
			System.out.println(f.getName() + "   创建时间:" + new SimpleDateFormat("yyyyMMDDHHmmss".format(new Date(millis));
			if(currentTime - millis > dayTime) {
				System.out.println("删除:" + deleteDirFile(f));
				// FileUtils.cleanDirectory(f);
			}
		}
	}

5,压缩文件

如图所示,想用Java实现将该目录下的文件压缩在一起成为一个zip文件:
在这里插入图片描述
代码实现:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @Author jingshuiliushen
 * @Date 2023/3/11 0:29
 */
public class ZipFile {

    public static void main(String[] args) {
        List<String> srcFiles = new ArrayList<>();
        srcFiles.add("D:\\练习题\\练习题\\练习题1.docx");
        srcFiles.add("D:\\练习题\\练习题\\练习题2.docx");
        srcFiles.add("D:\\练习题\\练习题\\练习题3.docx");
        srcFiles.add("D:\\练习题\\练习题\\练习题4.docx");
        srcFiles.add("D:\\练习题\\练习题\\练习题5.docx");
        srcFiles.add("D:\\练习题\\练习题\\练习题6.docx");
        System.out.println(zipFiles(srcFiles, "D:\\练习题\\练习题\\练习题.zip"));
    }

    public static boolean zipFiles(List<String> srcFiles, String zipFileName) {
        if (srcFiles == null || srcFiles.isEmpty()) {
            System.out.println("文件不存在");
            return false;
        }
        File zipFile = new File(zipFileName);
        try(FileOutputStream fileOutputStream = new FileOutputStream(zipFile);
            ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream)) {
            FileInputStream fileInputStream;
            for(String srcFile : srcFiles) {
                File file = new File(srcFile);
                // 单个文件不存在跳过
                if (!file.exists()) {
                    System.out.println(srcFile + "不存在");
                    continue;
                }
                fileInputStream = new FileInputStream(file);
                ZipEntry zipEntry = new ZipEntry(file.getName());
                zipOutputStream.putNextEntry(zipEntry);
                int len;
                byte[] buffer = new byte[1024];
                while ((len = fileInputStream.read(buffer)) > 0) {
                    zipOutputStream.write(buffer, 0, len);
                }
                fileInputStream.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }


    public static void zipFiles(File[] srcFiles, String zipFileName) {
        File zipFile = new File(zipFileName);
        try(FileOutputStream fileOutputStream = new FileOutputStream(zipFile);
            ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream)) {
            FileInputStream fileInputStream;
            for (File file : srcFiles) {
                fileInputStream = new FileInputStream(file);
                ZipEntry zipEntry = new ZipEntry(file.getName());
                zipOutputStream.putNextEntry(zipEntry);
                int len;
                byte[] buffer = new byte[1024];
                while ((len = fileInputStream.read(buffer)) > 0) {
                    zipOutputStream.write(buffer, 0, len);
                }
                fileInputStream.close();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException ioException) {
            ioException.printStackTrace();
        }
    }
}

运行结果:
在这里插入图片描述
代码可进行完善,结合删除可实现压缩后将原有文件删除,或者如果压缩的文件不存在就不要continue了,之间返回并提示某个文件不存在。

5,解压文件

    // 解压zip
    public static boolean unzipFile(String zipPath, String descDir) {
        if (!zipPath.contains("zip")) {
            System.out.println("file is not zip format");
        }
        File zipFile = new File(zipPath);
        if (!zipFile.exists()) {
            System.out.println("zipPath is not exist");
            return false;
        }
        // 解压到指定目录descDir为空字符,则默认解压到当前目录下
        if ("".equals(descDir)) {
            descDir = zipFile.getParent();
        }
        File pathFile = new File(descDir);
        if (!pathFile.exists()) {
            pathFile.mkdirs();
        }
        try (FileInputStream fileInputStream = new FileInputStream(zipPath);
             ZipInputStream zipInputStream = new ZipInputStream(fileInputStream)) {
            ZipEntry zipEntry;
            while ((zipEntry = zipInputStream.getNextEntry()) != null) {
                String zipEntryName = zipEntry.getName();
                String outPath = descDir + zipEntryName;
                File outFile = new File(outPath);
                if (zipEntry.isDirectory() && !outFile.exists()) {
                    outFile.mkdirs();
                }
                if (new File(outPath).isDirectory()) {
                    continue;
                }
                if (!writeZipToFile(zipInputStream, outPath)) {
                    return false;
                }
            }
        } catch (IOException ioException) {
            System.out.println("write file to zip error");
            return false;
        }
        return true;
    }

    private static boolean writeZipToFile(ZipInputStream zipInputStream, String filePath) {
        try (FileOutputStream fileOutputStream = new FileOutputStream(filePath)){
            byte[] bytes = new byte[1024];
            int len;
            while ((len = zipInputStream.read(bytes)) > 0) {
                fileOutputStream.write(bytes, 0, len);
            }
        } catch (IOException ioException) {
            System.out.println("write zip to file error");
            return false;
        }
        return true;
    }

如果出现java.lang.IllegalArgumentException: MALFORMED 异常,其原因是zip文件里含有中文名称的文件,windows 环境下,默认字符集为GBK,ZipFile 默认使用 UTF-8 字符集,当文件名存在中文时,处理时就会报错。解决办法为创建 ZipFile 时,设置字符集为GBK.

ZipInputStream zipInputStream = new ZipInputStream(fileInputStream, Charset.forName("GBK"))
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值