Java全栈JavaSE:25.File类和IO流

Posted new nm个对象

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java全栈JavaSE:25.File类和IO流相关的知识,希望对你有一定的参考价值。

第十四章 File类与IO流

14.1 java.io.File类

14.1.1 概述

File类是java.io包下代表与平台无关的文件和目录,也就是说如果希望在程序中操作文件和目录都可以通过File类来完成,File类能新建、删除、重命名文件和目录。

在API中File的解释是文件和目录路径名的抽象表示形式,即File类是文件或目录的路径,而不是文件本身,因此File类不能直接访问文件内容本身,如果需要访问文件内容本身,则需要使用输入/输出流。

File类代表磁盘或网络中某个文件或目录的路径名称,如:/atguigu/javase/io/佟刚.jpg

但不能直接通过File对象读取和写入数据,如果要操作数据,需要IO流。File对象好比是到水库的“路线地址”,要“存取”里面的水到你“家里”,需要“管道”。

14.1.2 构造方法

  • public File(String pathname) :通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。

  • public File(String parent, String child) :从父路径名字符串和子路径名字符串创建新的 File实例。

  • public File(File parent, String child) :从父抽象路径名和子路径名字符串创建新的 File实例。

  • 构造举例,代码如下:

// 文件路径名
String pathname = "D:\\\\aaa.txt";
File file1 = new File(pathname); 

// 文件路径名
String pathname2 = "D:\\\\aaa\\\\bbb.txt";
File file2 = new File(pathname2); 

// 通过父路径和子路径字符串
 String parent = "d:\\\\aaa";
 String child = "bbb.txt";
 File file3 = new File(parent, child);

// 通过父级File对象和子路径字符串
File parentDir = new File("d:\\\\aaa");
String child = "bbb.txt";
File file4 = new File(parentDir, child);

小贴士:

  1. 一个File对象代表硬盘中实际存在的一个文件或者目录。
  2. 无论该路径下是否存在文件或者目录,都不影响File对象的创建。

14.1.3 常用方法(了解)

1、获取文件和目录基本信息的方法

  • public String getName() :返回由此File表示的文件或目录的名称。

  • public long length() :返回由此File表示的文件的长度。

  • public String getPath() :将此File转换为路径名字符串。

  • public long lastModified():返回File对象对应的文件或目录的最后修改时间(毫秒值)

    方法演示,代码如下:

    import java.io.File;
    import java.time.Instant;
    import java.time.LocalDateTime;
    import java.time.ZoneId;
    
    public class TestFile 
        public static void main(String[] args) 
            File f = new File("d:/aaa/bbb.txt");     
            System.out.println("文件构造路径:"+f.getPath());
            System.out.println("文件名称:"+f.getName());
            System.out.println("文件长度:"+f.length()+"字节");
            System.out.println("文件最后修改时间:" + LocalDateTime.ofInstant(Instant.ofEpochMilli(f.lastModified()),ZoneId.of("Asia/Shanghai")));
    
            File f2 = new File("d:/aaa");     
            System.out.println("目录构造路径:"+f2.getPath());
            System.out.println("目录名称:"+f2.getName());
            System.out.println("目录长度:"+f2.length()+"字节");
            System.out.println("文件最后修改时间:" + LocalDateTime.ofInstant(Instant.ofEpochMilli(f.lastModified()),ZoneId.of("Asia/Shanghai")));
        
    
    
    输出结果:
    文件构造路径:d:\\aaa\\bbb.java
    文件名称:bbb.java
    文件长度:636字节
    文件最后修改时间:2019-07-23T22:01:32.065
    
    目录构造路径:d:\\aaa
    目录名称:aaa
    目录长度:4096字节
    文件最后修改时间:2019-07-23T22:01:32.065
    

API中说明:length(),表示文件的长度。但是File对象表示目录,则返回值未指定。

2、各种路径问题

  • public String getPath() :将此File转换为路径名字符串。
  • public String getAbsolutePath() :返回此File的绝对路径名字符串。
  • String getCanonicalPath():返回此File对象所对应的规范路径名。

File类可以使用文件路径字符串来创建File实例,该文件路径字符串既可以是绝对路径,也可以是相对路径。

默认情况下,系统总是依据用户的工作路径来解释相对路径,这个路径由系统属性“user.dir”指定,通常也就是运行Java虚拟机时所作的路径。

  • 绝对路径:从盘符开始的路径,这是一个完整的路径。
  • 相对路径:相对于项目目录的路径,这是一个便捷的路径,开发中经常使用。
  • 规范路径:所谓规范路径名,即对路径中的“…”等进行解析后的路径名
    @Test
    public void test1() throws IOException 
        File f1 = new File("d:\\\\atguigu\\\\javase\\\\HelloIO.java");
        System.out.println("文件/目录的名称:" + f1.getName()); // `文件/目录的名称:HelloIO.java`
        System.out.println("文件/目录的构造路径名:" + f1.getPath()); // `文件/目录的构造路径名:d:\\atguigu\\javase\\HelloIO.java`
        System.out.println("文件/目录的绝对路径名:" + f1.getAbsolutePath()); // `文件/目录的绝对路径名:d:\\atguigu\\javase\\HelloIO.java`
        System.out.println("文件/目录的规范路径名:" + f1.getCanonicalPath()); // `文件/目录的规范路径名:D:\\atguigu\\javase\\HelloIO.java`
        System.out.println("文件/目录的父目录名:" + f1.getParent()); // `文件/目录的父目录名:d:\\atguigu\\javase`
    
    @Test
    public void test2() throws IOException
        File f2 = new File("HelloIO.java");
        System.out.println("文件/目录的名称:" + f2.getName()); // `文件/目录的名称:HelloIO.java`
        System.out.println("文件/目录的构造路径名:" + f2.getPath()); // `文件/目录的构造路径名:HelloIO.java`
        System.out.println("文件/目录的绝对路径名:" + f2.getAbsolutePath()); // `文件/目录的绝对路径名:E:\\Java全栈\\code\\JavaSE\\HelloIO.java`
        System.out.println("文件/目录的规范路径名:" + f2.getCanonicalPath()); // `文件/目录的规范路径名:E:\\Java全栈\\code\\JavaSE\\HelloIO.java`
        System.out.println("文件/目录的父目录名:" + f2.getParent());// null
    
    @Test
    public void test3() throws IOException
        File f3 = new File("../../HelloIO.java");
        System.out.println("文件/目录的名称:" + f3.getName()); // `文件/目录的名称:HelloIO.java`
        System.out.println("文件/目录的构造路径名:" + f3.getPath()); // `文件/目录的构造路径名:..\\..\\HelloIO.java`
        System.out.println("文件/目录的绝对路径名:" + f3.getAbsolutePath()); // `文件/目录的绝对路径名:E:\\Java全栈\\code\\JavaSE\\..\\..\\HelloIO.java`
        System.out.println("文件/目录的规范路径名:" + f3.getCanonicalPath()); // `文件/目录的规范路径名:E:\\Java全栈\\HelloIO.java`
        System.out.println("文件/目录的父目录名:" + f3.getParent());// `..\\..`
    
  • window的路径分隔符使用“\\”,而Java程序中的“\\”表示转义字符,所以在Windows中表示路径,需要用“\\”。或者直接使用“/”也可以,Java程序支持将“/”当成平台无关的路径分隔符。或者直接使用File.separator常量值表示。

  • 把构造File对象指定的文件或目录的路径名,称为构造路径,它可以是绝对路径,也可以是相对路径

  • 当构造路径是绝对路径时,那么getPath和getAbsolutePath结果一样

  • 当构造路径是相对路径时,那么getAbsolutePath的路径 = user.dir的路径 + 构造路径

  • 当路径中不包含"…“和”/开头"等形式的路径,那么规范路径和绝对路径一样,否则会将…等进行解析。路径中如果出现“…”表示上一级目录,路径名如果以“/”开头,表示从“根目录”下开始导航。

3、判断功能的方法

  • public boolean exists() :此File表示的文件或目录是否实际存在。
  • public boolean isDirectory() :此File表示的是否为目录。
  • public boolean isFile() :此File表示的是否为文件。

方法演示,代码如下:

public class FileIs 
    public static void main(String[] args) 
        File f = new File("d:\\\\aaa\\\\bbb.java");
        File f2 = new File("d:\\\\aaa");
      	// 判断是否存在
        System.out.println("d:\\\\aaa\\\\bbb.java 是否存在:"+f.exists());
        System.out.println("d:\\\\aaa 是否存在:"+f2.exists());
      	// 判断是文件还是目录
        System.out.println("d:\\\\aaa 文件?:"+f2.isFile());
        System.out.println("d:\\\\aaa 目录?:"+f2.isDirectory());
    

输出结果:
d:\\aaa\\bbb.java 是否存在:true
d:\\aaa 是否存在:true
d:\\aaa 文件?:false
d:\\aaa 目录?:true

如果文件或目录不存在,那么isFile()和isDirectory()都是返回false

4、创建删除功能的方法

  • public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
  • public boolean delete() :删除由此File表示的文件或目录。 只能删除空目录。
  • public boolean mkdir() :创建由此File表示的目录。
  • public boolean mkdirs() :创建由此File表示的目录,包括任何必需但不存在的父目录。

方法演示,代码如下:

public class FileCreateDelete 
    public static void main(String[] args) throws IOException 
        // 文件的创建
        File f = new File("aaa.txt");
        System.out.println("是否存在:"+f.exists()); // false
        System.out.println("是否创建:"+f.createNewFile()); // true
        System.out.println("是否存在:"+f.exists()); // true
		
     	// 目录的创建
      	File f2= new File("newDir");	
        System.out.println("是否存在:"+f2.exists());// false
        System.out.println("是否创建:"+f2.mkdir());	// true
        System.out.println("是否存在:"+f2.exists());// true

		// 创建多级目录
      	File f3= new File("newDira\\\\newDirb");
        System.out.println(f3.mkdir());// false
        File f4= new File("newDira\\\\newDirb");
        System.out.println(f4.mkdirs());// true
      
      	// 文件的删除
       	System.out.println(f.delete());// true
      
      	// 目录的删除
        System.out.println(f2.delete());// true
        System.out.println(f4.delete());// false
    

API中说明:delete方法,如果此File表示目录,则目录必须为空才能删除。

14.1.4 递归实现多级目录操作(了解,有时间作为复习递归练习用)

  • public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。

  • public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。

  • public File[] listFiles(FileFilter filter):返回所有满足指定过滤器的文件和目录。如果给定 filter 为 null,则接受所有路径名。否则,当且仅当在路径名上调用过滤器的 FileFilter.accept(java.io.File) 方法返回 true 时,该路径名才满足过滤器。如果当前File对象不表示一个目录,或者发生 I/O 错误,则返回 null。

1、递归打印多级目录

分析:多级目录的打印。遍历之前,无从知道到底有多少级目录,所以我们可以使用递归实现。

代码实现

	@Test
	public void test3() 
		 File dir = new File("d:/atguigu");
		 listSubFiles(dir);
	

	public void listSubFiles(File dir) 
		if (dir != null && dir.isDirectory()) 
			File[] listFiles = dir.listFiles();
			if (listFiles != null) 
				for (File sub : listFiles) 
					listSubFiles(sub);//递归调用
				
			
		
		System.out.println(dir);
	

2、递归打印某目录下(包括子目录)中所有满足条件的文件

示例代码:列出"D:/atguigu"下所有".java"文件

	@Test
	public void test5() 
		 File dir = new File("D:/atguigu");
		 listByFileFilter(dir);
	
	
	public void listByFileFilter(File file) 
		if (file != null && file.isDirectory()) 
			File[] listFiles = file.listFiles(new FilenameFilter() 

				@Override
				public boolean accept(File dir, String name) 
					return name.endsWith(".java") || new File(dir,name).isDirectory();
				
			);
			if (listFiles != null) 
				for (File sub : listFiles) 
					if(sub.isFile())
						System.out.println(sub);
					
					listByFileFilter(sub);
				
			
		
	

3、递归求目录总大小

	@Test
	public void test4() 
		 File dir = new File("D:/atguigu");
		 long length = getLength(dir);
		 System.out.println("大小:" + length);
	
	
	public long getLength(File dir)
		if (dir != null && dir.isDirectory()) 
			File[] listFiles = dir.listFiles();
			if(listFiles!=null)
				long sum = 0;
				for (File sub : listFiles) 
					sum += getLength(sub);
				
				return sum;
			
		else if(dir != null && dir.isFile())
			return dir.length();
		
		return 0;
	

4、递归删除非空目录

如果目录非空,连同目录下的文件和文件夹一起删除

	@Test
	public void test6() 
		 File dir = new File("D:/atguigu/javase");
		 forceDeleteDir(dir);
	
	public void forceDeleteDir(File dir) 
		if (dir != null && dir.isDirectory()) 
			File[] listFiles = dir.listFiles();
			if(listFiles!=null)
				for (File sub : listFiles) 
					forceDeleteDir(sub);
				
			
		
		dir.delete();
	

14.2 IO概述

1、什么是IO

生活中,你肯定经历过这样的场景。当你编辑一个文本文件,忘记了ctrl+s ,可能文件就白白编辑了。当你电脑上插入一个U盘,可以把一个视频,拷贝到你的电脑硬盘里。那么数据都是在哪些设备上的呢?键盘、内存、硬盘、外接设备等等。

我们把这种数据的传输,可以看做是一种数据的流动,按照流动的方向,以内存为基准,分为输入input输出output ,即流向内存是输入流,流出内存的输出流。

Java中I/O操作主要是指使用java.io包下的内容,进行输入、输出操作。输入也叫做读取数据,输出也叫做作写出数据。

2、IO的分类

根据数据的流向分为:输入流输出流