创作不易,如果觉得这篇文章对你有帮助,欢迎各位老铁点个赞呗,您的支持是我创作的最大动力!
Java中的File类,在实际开发中用的还是比较多的,比如说读取资源时,文件上传下载时等场景,这里做一下总结,以后使用的时候,可以很方便的查询api。
Java文件类以抽象的方式代表文件名和目录路径名。该类主要用于文件和目录的创建
、文件的查找
和文件的删除
等。
File
对象代表磁盘中实际存在的文件和目录。
可以通过以下四种构造方法其中一个,来创建一个File对象:
通过给定的父抽象路径名和子路径名字符串创建一个新的File实例
File(File parent, String child)
通过将给定路径名字符串转换成抽象路径名来创建一个新 File 实例
File(String pathname)
根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例
File(String parent, String child)
通过将给定的 file: URI 转换成一个抽象路径名来创建一个新的 File 实例
File(URI uri)
创建File对象成功后,可以使用以下表格中的方法来操作文件:
序号 | 方法名称 | 方法描述 |
---|---|---|
1 | public String getName() |
返回由此抽象路径名表示的文件或目录的名称 |
2 | public String getParent() | 返回此抽象路径名的父路径名的路径名字符串,如果此路径名没有指定父目录,则返回 null |
3 | public File getParentFile() |
返回此抽象路径名的父路径名的抽象路径名,如果此路径名没有指定父目录,则返回 null |
4 | public String getPath() | 将此抽象路径名转换为一个路径名字符串 |
5 | public boolean isAbsolute() | 判断此抽象路径名是否为绝对路径名 |
6 | public String getAbsolutePath() |
返回抽象路径名的绝对路径名字符串 |
7 | public boolean canRead() | 判断应用程序是否可以读取此抽象路径名表示的文件 |
8 | public boolean canWrite() | 判断应用程序是否可以修改此抽象路径名表示的文件 |
9 | public boolean exists() |
判断此抽象路径名表示的文件或目录是否存在 |
10 | public boolean isDirectory() |
判断此抽象路径名表示的文件是否是一个目录 |
11 | public boolean isFile() |
判断此抽象路径名表示的文件是否是一个标准文件 |
12 | public long lastModified() | 返回此抽象路径名表示的文件最后一次被修改的时间 |
13 | public long length() | 返回由此抽象路径名表示的文件的长度 |
14 | public boolean createNewFile() throws IOException | 当且仅当不存在具有此抽象路径名指定的名称的文件时,原子地创建由此抽象路径名指定的一个新的空文件 |
15 | public boolean delete() |
删除此抽象路径名表示的文件或目录 |
16 | public void deleteOnExit() | 在虚拟机终止时,请求删除此抽象路径名表示的文件或目录 |
17 | public String[] list() | 返回由此抽象路径名所表示的目录中的文件和目录的名称所组成字符串数组 |
18 | public String[] list(FilenameFilter filter) | 返回由包含在目录中的文件和目录的名称 所组成的字符串数组,这一目录是通过满足指定过滤器的抽象路径名来表示的 |
19 | public File[] listFiles() |
返回一个抽象路径名数组,这些路径名表示此抽象路径名所表示目录中的文件 |
20 | public File[] listFiles(FileFilter filter) | 返回表示此抽象路径名所表示目录中的文件和目录的抽象路径名数组,这些路径名满足特定过滤器 |
21 | public boolean mkdir() |
创建此抽象路径名指定的目录 |
22 | public boolean mkdirs() |
创建此抽象路径名指定的目录,包括创建必需但不存在的父目录 |
23 | public boolean renameTo(File dest) | 重新命名此抽象路径名表示的文件 |
24 | public boolean setLastModified(long time) | 设置由此抽象路径名所指定的文件或目录的最后一次修改时间 |
25 | public boolean setReadOnly() | 标记此抽象路径名指定的文件或目录,以便只可对其进行读操作 |
26 | public static File createTempFile(String prefix, String suffix, File directory) throws IOException | 在指定目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称 |
27 | public static File createTempFile(String prefix, String suffix) throws IOException | 在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称 |
28 | public int compareTo(File pathname) | 按字母顺序比较两个抽象路径名 |
29 | public int compareTo(Object o) | 按字母顺序比较抽象路径名与给定对象 |
30 | public boolean equals(Object obj) | 判断此抽象路径名与给定对象是否相等 |
31 | public String toString() | 返回此抽象路径名的路径名字符串 |
【代码示例】
/**
* @author smilehappiness
* File对象中,基础api的使用
* @version 1.0
* @ClassName FileUse
* @Date 2020/6/6 15:40
*/
public class FileUse {
public static void main(String args[]) {
//测试的目录名称
String dirName = "d:\\test-case";
File file = new File(dirName);
//判断此抽象路径名,是不是目录类型
if (file.isDirectory()) {
System.out.println("Directory of " + dirName);
//返回由此抽象路径名所表示的目录中的文件和目录的名称所组成字符串数组
String stringArrays[] = file.list();
for (int i = 0; i < stringArrays.length; i++) {
File f = new File(dirName + "/" + stringArrays[i]);
if (f.isDirectory()) {
System.out.println(stringArrays[i] + " is a directory");
} else {
System.out.println(stringArrays[i] + " is a file");
}
}
System.out.println("------------------华丽的分割线------------------");
//返回一个抽象路径名数组,这些路径名表示此抽象路径名所表示目录中的文件
File fileArrays[] = file.listFiles();
for (File fileArray : fileArrays) {
File f = new File(dirName + "/" + fileArray);
if (f.isDirectory()) {
System.out.println(fileArray + " is a directory");
} else {
System.out.println(fileArray + " is a file");
}
}
//判断此抽象路径名,是不是标准文件类型
} else if (file.isFile()) {
System.out.println(dirName + " is not a directory");
}
}
}
执行结果:
Directory of d:\test-case
hello is a directory
log.txt is a file
Person.dat is a file
test.txt is a file
test.txt.bak is a file
------------------华丽的分割线------------------
d:\test-case\hello is a file
d:\test-case\log.txt is a file
d:\test-case\Person.dat is a file
d:\test-case\test.txt is a file
d:\test-case\test.txt.bak is a file
项目中,目前普遍使用maven进行项目的构建,但是使用maven时,由于网络不稳定,或者需要等因素,导致部分jar可能下载失败,只能重新下载才能使项目正常启动,但是下载失败的依赖,如果你不删除,又下载不成功,导致项目启动报错。
如何快速找到哪个依赖报错了呢?找到失败的依赖,删除后,重新下载,绝大多数就成功了,不多唠叨了,见以下解决方案示例:
/**
* @author smilehappiness
*
* 通过读取指定的目录及子目录下指定文件名的路径,获取需要的资源,返回结果为List
* @version 1.0
* @ClassName MavenFailDependency
* @Date 2020/6/6 14:13
*/
public class MavenFailDependency {
/**
*
* 通过指定路径和匹配的内容后缀,来获取目录下的资源文件
*
*
* @param path 文件路径
* @param suffix 后缀名, 匹配具体的后缀内容的文件
* @return java.util.List
* @Date 2020/6/6 14:20
*/
public static List<String> getFilesList(String path, String suffix) {
File file = new File(path);
return MavenFailDependency.listFile(new ArrayList<>(), file, suffix);
}
/**
*
* 获取目录下,指定后缀内容的资源文件
* 如:这下失败的依赖 aether-ed239b5e-5ab7-49c1-8f71-df76605fb76e-spring-beans-5.0.5.RELEASE.jar.sha1-in-progress
* 以in-progress为结尾的为下载失败的依赖,常见的下载依赖失败的后缀,.sha1-in-progress/.jar-in-progress/.pom-in-progress
*
*
* @param fileNameList
* @param file
* @param suffix
* @return java.util.List
* @Date 2020/6/6 14:30
*/
private static List<String> listFile(List<String> fileNameList, File file, String suffix) {
if (StringUtils.isBlank(suffix)) {
return Collections.emptyList();
}
// 若是目录, 采用递归的方法遍历子目录(file.isFile()、file.isDirectory())
if (file.isDirectory()) {
// 获取源目录中所有的子文件(子文件中有目录,也有可能有文件)
File[] fileList = file.listFiles();
for (File subFile : fileList) {
//递归调用
listFile(fileNameList, subFile, suffix);
}
} else {
// 获取文件的绝对路径
String filePath = file.getAbsolutePath();
// 最后一个.(即后缀名前面的.)的索引
int begIndex = filePath.lastIndexOf(".");
// 这里可以筛选指定后缀的文件
if (begIndex != -1) {
//获取到最后一个.结尾后面的内容
String suffixValue = filePath.substring(begIndex + 1);
// sha1-in-progress包含in-progress
// 这里因为指定的后缀与截取.的后缀,名字不一致,所以加一个 || tempSuffix.contains(suffix)条件
if (suffixValue.equals(suffix) || suffixValue.contains(suffix)) {
fileNameList.add(filePath);
}
}
}
return fileNameList;
}
}
测试用例:
/**
*
* 快速获取,maven仓库中,失败的依赖,找到失败的依赖,删除后,重新下载,功能测试
*
*
* @author smilehappiness
* @Date 2020/6/6 14:55
*/
public class MavenFailDependencyTest {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Test
public void testGetMavenFailDependency() {
//本地maven仓库,依赖下载保存的地址
String localMavenRepositoryDir = "D:\\workplace\\worktool\\maven";
List<String> list = MavenFailDependency.getFilesList(localMavenRepositoryDir, "in-progress");
logger.info("依赖下载失败的个数:{}", list.size());
if (CollectionUtils.isNotEmpty(list)) {
for (int i = 0; i < list.size(); i++) {
logger.info("依赖下载失败的目录{}:{}", i, list.get(i));
}
}
}
}
给老铁们总结一个拷贝工具类:
/**
*
* 文件拷贝工具类
*
*
* @author smilehappiness
* @Date 2020/6/6 11:56
*/
public class FileCopyUtil {
private FileCopyUtil() {
}
/**
*
* 拷贝文件的功能
*
*
* @param srcFile 源文件(路径)
* @param desPath 目标路径
* @return void
* @Date 2020/6/6 11:57
*/
public static void copyFile(String srcFile, String desPath) {
// String -> File
copyFile(new File(srcFile), desPath);
}
/**
*
* 拷贝文件的功能
*
*
* @param srcFile 源文件(file类型)
* @param desPath 目标路径
* @return void
* @Date 2020/6/6 12:01
*/
public static void copyFile(File srcFile, String desPath) {
// 1.取出源文件名称
String fileName = srcFile.getName();
// 2.判断目标路径是否存在
File dPath = new File(desPath);
if (!dPath.exists()) {
//拷贝的目的地路径,如果目录不存在,创建目录
// boolean mkdir() 创建此抽象路径名指定的目录,创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。
System.out.println("创建目标路径是否成功:" + dPath.mkdirs());
}
// 3.设置目标文件名称
//static String separator() 与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。
String desFileName = desPath + File.separator + fileName;
// 声明低级流
FileInputStream fileInputStream;
FileOutputStream fileOutputStream;
// 声明高级流
BufferedInputStream bufferedInputStream = null;
BufferedOutputStream bufferedOutputStream = null;
try {
// 初始化的时候先初始化低级流(FileInputStream为文件字节输入流,FileOutputStream为文件字节输出流)
fileInputStream = new FileInputStream(srcFile);
fileOutputStream = new FileOutputStream(desFileName);
// 然后初始化高级流,使用缓冲流提升io性能
bufferedInputStream = new BufferedInputStream(fileInputStream);
bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
//定义一个字节数组,相当于缓存
byte[] b = new byte[1024 * 1024];
//得到实际读取到的字节数 读到最后返回-1
int i = 0;
//循环读取,把bufferedInputStream里的东西读到bytes数组里去
while ((i = bufferedInputStream.read(b)) != -1) {
bufferedOutputStream.write(b, 0, i);
}
System.out.println(srcFile + " 文件拷贝到目标目录【" + desPath + "】完成!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 高级流bout关闭的时候,JVM会自动的刷新缓冲区,即在关闭流之前会自动调用flush方法刷新缓存
try {
if (bufferedOutputStream != null) {
bufferedOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (bufferedInputStream != null) {
bufferedInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
*
* 拷贝目录的功能
*
*
* @param srcPath 源目录(路径)
* @param desPath 目标目录
* @return void
* @Date 2020/6/6 13:13
*/
public static void copyDir(String srcPath, String desPath) {
copyDir(new File(srcPath), desPath);
}
/**
*
* 拷贝目录的功能
*
*
* @param srcPath 源目录(file类型)
* @param desPath 目标目录
* @return void
* @Date 2020/6/6 13:20
*/
public static void copyDir(File srcPath, String desPath) {
// 判断srcPath是文件还是目录
if (srcPath.isFile()) {
// 递归调用,如果是文件则继续调用,直到为一个目录
copyFile(srcPath, desPath);
} else {
// 获取源目录中所有的子文件
File[] files = srcPath.listFiles();
// 从源目录中获取要拷贝的目录的名称,例如:从"d:\\test-case"源目录中获取到 test-case 这个目录的名称
String srcPathName = srcPath.getName();
// 在目标路径中创建要拷贝的目录名称,例如 在d:\\创建 src 目录
String descPathName = desPath + File.separator;
// 通过将给定路径名字符串,转换为抽象路径名,来创建一个新 File 实例
File filePath = new File(descPathName);
// 创建此抽象路径名指定的目录,包括所有必需但不存在的父目录
if (!filePath.exists()) {
filePath.mkdirs();
}
// 遍历数组,一个一个目录的拷贝
for (File file : files) {
// 递归调用
copyDir(file, descPathName);
}
}
}
}
/**
*
* 拷贝文件的功能-测试
*
*
* @param
* @return void
* @Date 2020/6/6 13:33
*/
@Test
public void testCopyFile() {
String srcFile = "D:\\test-case\\log.txt";
FileCopyUtil.copyFile(srcFile, "d:\\test-case\\src");
}
/**
*
* 拷贝目录的功能
*
*
* @param
* @return void
* @Date 2020/6/6 13:43
*/
@Test
public void testCopyDir() {
String srcFile = "D:\\test-case";
FileCopyUtil.copyDir(srcFile, "c:\\test-case\\test");
}
分布式系统项目中,部署测试的时候,需要打jar包部署。为了方便把jar资源上传到uat服务器,可以把maven成功打包后的jar资源统一备份到指定目录,方便使用。
基础实现代码如下:
package cn.smilehappiness;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.io.FileFilter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Pattern;
/**
*
* 拷贝项目打包后的jar,到指定的目录,方便后续部署测试
*
*
* @author smilehappiness
* @Date 2020/7/3 10:13
*/
public class CopyJarToTargetUtil {
public static void main(String[] args) throws Exception {
String srcPath = "D:\\workplace\\git_project\\project-name";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String currentDate = sdf.format(new Date());
String targetDir = StringUtils.join("D:\\jar-back", "\\", currentDate, "-back-jar");
CopyJarToTargetUtil.copyJar(new File(srcPath), targetDir);
System.out.println("资源文件拷贝完成!");
}
/**
*
* 拷贝资源,把源文件拷贝到指定目录
*
*
* @param srcFilePath
* @param targetFilePath
* @return java.lang.String
* @Date 2020/7/3 10:24
*/
public static String copyJar(File srcFilePath, String targetFilePath) throws Exception {
File targetFile = new File(targetFilePath);
//如果目标目录不存在,则创建目录
if (!targetFile.exists()) {
targetFile.mkdirs();
}
if (srcFilePath.exists() && srcFilePath.isDirectory()) {
//获取指定目标目录下,过滤后的资源文件列表
File[] files = srcFilePath.listFiles(new MyFileFilter());
for (File file : files) {
if (file.isDirectory()) {
//过滤git目录
if (file.getName().endsWith(".git") || file.getName().endsWith(".idea")) {
continue;
}
//递归处理
copyJar(file, targetFilePath);
} else {
File targetSourceFile = new File(targetFilePath + "\\" + file.getName());
FileUtils.copyFile(file, targetSourceFile);
}
}
return "success";
} else {
return "文件路径不存在";
}
}
/**
*
* 过滤 *.jar文件
*
*
* @author smilehappiness
* @Date 2020/7/3 10:20
*/
static class MyFileFilter implements FileFilter {
@Override
public boolean accept(File file) {
String fileName = file.getName().toLowerCase();
/*String regex = "^[A-Za-z-]*-impl-[0-9.]+.jar$";
Pattern compile = Pattern.compile(regex);
boolean flag = compile.matcher(fileName).matches();*/
String regex = "^[A-Za-z-]*-impl-[0-9.]+.jar$";//hello-word-impl-1.0.0.jar
boolean flag = Pattern.matches(regex, fileName);
if (flag || file.isDirectory()) {
return true;
}
return false;
}
}
}
本文主要介绍了Java中File对象基础api的使用。笔者使用File类常用的api方法,写了一些案例,给老铁们加深api方法的印象。File对象,相对来说用的还是比较多的,希望老铁们多多联系和掌握。
参考资料:https://www.runoob.com/java/java-file.html
写博客是为了记住自己容易忘记的东西,另外也是对自己工作的总结,希望尽自己的努力,做到更好,大家一起努力进步!
如果有什么问题,欢迎大家评论,一起探讨,代码如有问题,欢迎各位大神指正!
给自己的梦想添加一双翅膀,让它可以在天空中自由自在的飞翔!