java_IO--文件操作
内容学习于:edu.aliyun.com
1. File类基本使用
在Java语言里面提供有对于文件操作系统操作的支持,而这个支持就在java.
io.File类中进行了定义,也就是说在整个java.io包里面,File 类是唯一一个与文件本身操作(创建、删除、重命名等等)有关的类,而如果要想进行File 类的操作,必须要提供有完整的路径,而后可以调用相应的方法进行处理。
打开JDK文档可以发现,File 类是Comparable接口的子类,所以<mark>File类的对象是可以进行排序处理的</mark>。而在进行File类处理的时候需要为其设置访问路径,那么对于路径的配置主要通过File类的构造方法处理:
<mark>只是用于创建文件,文件的内容无法设定。</mark>
- <mark>构造方法:File(String pathname),设置要操作的完整路径</mark>
- 构造方法:File(File parent, String child),设置父路径与子目录
如果现在要想进行文件的基本操作,可以使用如下的方法:
- 创建新文件:public boolean createNewFile() throws IOException
- 如果文件不存在返回true,否则返回false
- <mark>判断文件是否存在:public boolean exists()</mark>
- <mark>删除文件:public boolean delete()</mark>
创建一个mldn.txt文件:
public class JavaAPIDemo {
public static void main(String[] args) throws Exception {
File file = new File("d:\\mldn.txt");
if(file.exists()){//如果文件存在
file.delete();//先删除该文件再创建
System.out.println(file.createNewFile());
}else {
System.out.println(file.createNewFile());//直接创建
}
}
}
结果:
true
2. 文件类深入操作
现在已经实现了文件的基础操作,但是对于这个操作里面也是存在有一些问题的,下面针对于之前的代码进行优化处理。
1、在实际的软件项目开发和运行的过程之中,往往都会在Windows中进行项目的开发,而在项目部署的时候基于Linux或Unix系统来进行项目发布以保证生产环节的安全性;在不同的操作系统之中会存在有不同的路径分割符: Windows 分隔符“\”、Linux 分隔符“/”, 所以在最初进行开发的时候就必须考虑不同系统环境下的分隔符的问题,所以为了解决此问题,File 类提供有一个常量: <mark>public static final String separator;</mark>
建议还是使用这个:
<mark>标准的文件路径编写格式:File file = new File(“d:”+File.separator+“mldn.txt”);</mark>
Linux方式命名在Windows下也能执行:File file = new File(“d:/mldn.txt”);
2、在使用 File类进行文件处理的时候需要注意的是:程序→JVM→操作系统函数→文件处理,所以在进行同一文件的的反复删除或创建的时候有可能会出现有延迟的问题,<mark>所以这个时候最好的方案是别重名;</mark>
3、在进行文件创建的时候有一个重要的前提:文件的父路径必须首先存在。
如果父路径没有创建,会报错:Exception in thread “main” java.io.IOException: 系统找不到指定的路径。
- 获取父路径:public File getParentFile()
- 创建目录(多级):public boolean mkdirs()
- 创建目录(单级):public boolean mkdir()
创建父路径:
public class JavaAPIDemo {
public static void main(String[] args) throws Exception {
File file = new File("d:" + File.separator + "aaaaaa" + File.separator + "bbbbbb" + File.separator + "mldn.txt");
if (!file.getParentFile().exists()) {//判断父路径是否存在
file.mkdirs();//创建多级路径
}
if (file.exists()) {//如果文件存在
file.delete();//先删除该文件再创建
System.out.println(file.createNewFile());
} else {
System.out.println(file.createNewFile());//直接创建
}
}
}
结果:
true
这种判断并且建立父目录的操作在很多的情况下可能只需要一次,但是如果将这个判断一直都停留在代码里面,那么就会造成时间复杂度的提升,<mark>所以这个时候如果要想提升性能,请先保证目录已经创建。</mark>
3. 获取文件信息
除了可以进行文件的操作之外也可以通过File类来获取一些文件本身提供的信息,可以获取如下内容:
- 可读:public boolean canRead()
- 可写:public boolean canWrite()
- 获取文件长度:public long length(),该方法返回的是一个long数据类型,字节长度
最后一次的操作修改时间:public long lastModified()- 判断是否是目录:public boolean isDirectory()
- 判断是否是文件:public boolean isFile()
上述方法的操作演示:
class MathUtil {
/** * 指定位数的四舍五入 * * @param num 待四射五入数字 * @param scale 保留的位数 * @return 四舍五入后的数字 */
public static double round(double num, int scale) {
return Math.round(Math.pow(10, scale) * num) / Math.pow(10, scale);
}
}
public class JavaAPIDemo {
public static void main(String[] args) throws Exception {
File file = new File("d:" + File.separator + "bizhi" + File.separator + "timg.jpg");
System.out.println("文件是否可读:" + file.canRead());
System.out.println("文件是否可写:" + file.canWrite());
System.out.println("文件的大小:" + MathUtil.round(file.length() / (double) 1024, 2) + "k");
System.out.println("最后一次文件的修改日期:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(file.lastModified())));
System.out.println("是目录吗?" + file.isDirectory());
System.out.println("是文件吗?" + file.isFile());
}
}
结果:
文件是否可读:true
文件是否可写:true
文件的大小:19.28k
最后一次文件的修改日期:2018-01-10 13:16:51
是目录吗?false
是文件吗?true
既然可以判断给定的路径是文件还是目录,那么就可以进一步的判断, 如果发现是目录,则应该列出目录中的全部内容:
- 列出目录文件:public File[] listFiles()
代码:
public class JavaAPIDemo {
public static void main(String[] args) throws Exception {
File file = new File("d:" + File.separator + "工作学习");
if (file.isDirectory()) {//判断是否是目录
File result[] = file.listFiles();//获得目录下所有内容
for (File t : result) {//输出该内容
System.out.println(t);
}
}
}
}
结果:
d:\工作学习\Adobe Photoshop CS6
d:\工作学习\photoshop
d:\工作学习\文件稿子
d:\工作学习\活动部
d:\工作学习\编程
这些信息的获得都是文件或目录本身的操作,<mark>都是不涉及到文件内容处理的。</mark>
4. 综合案例: 列出指定目录下的全部文件(递归)
现在可以由开发者任意设置一个目录的路径,而后将这个目录中所有的文件的信息全部列出,包括子目录中的所有文件,在这样的处理情况下最好的做法就是利用递归的形式来完成。
代码:
public class JavaAPIDemo {
public static void main(String[] args) throws Exception {
File file = new File("d:" + File.separator + "aaaa");
listDir(file);
}
private static void listDir(File file) {
if (file.isDirectory()) {//判断是否是目录
File[] results = file.listFiles();//获取目录下的所有内容
for (File t : results) {
listDir(t);//递归调用
}
}
System.out.println(file);
}
}
结果:
d:\aaaa\1\1.1\1.1.1
d:\aaaa\1\1.1
d:\aaaa\1\1.2
d:\aaaa\1
d:\aaaa\2
d:\aaaa
5. 综合案例: 批量修改文件名称(递归)
编写程序,程序运行时输入目录名称,并把该目录下的所有文件名后缀修改为.txt。对于这类的操作必须设置一些假设的约定,能够重命名的文件都是有后缀的,如果没有后缀的路径,则为其追加路径,如果有后缀的路径,则必须以最后一个“.”进行截取。
代码:
public class JavaAPIDemo {
public static void main(String[] args) throws Exception {
File file = new File("d:" + File.separator + "aaaa");
renameDir(file);
}
private static void renameDir(File file) {
if (file.isDirectory()) {//判断是否是目录
File[] results = file.listFiles();//获取目录下的所有内容
if (results != null) {
for (File t : results) {
renameDir(t);//递归调用
}
}
} else {
if (file.isFile()) {//判断是否是文件
String fileName = null;
if (file.getName().contains(".")) {//判断文件名称是否由“.”
fileName = file.getName().substring(0, file.getName().lastIndexOf(".")) + ".txt";//截取文件后缀前面的名称并加上后缀“.txt”
} else fileName = file.getName() + "txt";
File newFile = new File(file.getParent(), fileName);//新文件的名称
file.renameTo(newFile);//文件重命名
}
}
}
}