34File类、IO流【字节流】

本文详细介绍了Java中的File类,包括其用于表示文件和目录路径,以及如何获取文件信息、处理相对和绝对路径。此外,讲解了如何通过IO流进行文件操作,涉及字节流和字符流的应用,以及如何处理文件存在、复制和异常情况。
摘要由CSDN通过智能技术生成

day34

File类

理解

File是文件和目录路径名的抽象表示

File类的对象可以表示文件:D:\笔记\奇男子\qnz.txt

File类的对象可以表示目录路径名:D:\笔记\奇男子

File只关注文件本身的信息(文件名、是否可读、是否可写…),而不能操作文件里面的内容

File类 – 表示文件或文件夹,不能对文件里的数据进行操作

对文件里的数据进行操作的是:IO流

需求1:

通过程序,获取已知文件的信息

public class Test01 {

	public static void main(String[] args) {
		
		//创建file对象
		File file = new File("D:\\笔记\\奇男子\\qnz.txt");
		
		System.out.println("获取文件路径:" + file.getAbsolutePath());
		System.out.println("获取文件名:" + file.getName());
		System.out.println("获取文件是否可读:" + file.canRead());
		System.out.println("获取文件是否可写:" + file.canWrite());
		System.out.println("获取文件是否隐藏:" + file.isHidden());
		System.out.println("获取文件大小(字节):" + file.length());

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
		String datetime = sdf.format(file.lastModified());
		System.out.println("获取文件最后修改时间:" + datetime);
	}
}

相对路径 和 绝对路径

绝对路径:

从根目录开始的完整路径,包含了文件系统中该文件或目录

理解:所在的完整路径,通常以根目录符号(如Linux中的“/”,Windows中的“C:\”)开始

相对路径:

相对于当前项目下的路径

public class Test02 {

	public static void main(String[] args) {
		
		File file = new File("file.txt");//使用的是相对路径
		System.out.println(file.length());
		
		//D:\workspace\MyDay33\file.txt
		System.out.println("绝对路径:" + file.getAbsolutePath());
		
		//file.txt
		System.out.println("相对路径:" + file.getPath());
		
	}
}

需求2

通过程序,判断指定路径的文件是否存在,如果不存在,则创建该文件
下面按各种情况来解决该问题

1)目录已存在的情况

如果目录不存在就会报错,找不到系统路径

public class Test01 {
	public static void main(String[] args) throws IOException {
		
		File file = new File("file01\\hhy.txt");
		
		//判断文件是否存在
		if(!file.exists()){
			//创建文件
			file.createNewFile();
		}
	}
}
2)有一个层级的目录不存在的情况
public class Test02 {
	public static void main(String[] args) throws IOException {
		
		//D:\workspace\MyDay34\file01\qnz.txt
		File file = new File("file01\\qnz.txt");
		
		//获取父路径 -- D:\workspace\MyDay34\file01
		File parentFile = file.getParentFile();
		//判断父路径是否存在
		if(!parentFile.exists()){
			//创建一层目录
			parentFile.mkdir();
		}
		
		//判断文件是否存在
		if(!file.exists()){
			//创建文件
			file.createNewFile();
		}
	}
}
3)有多个层级的目录不存在的情况
public class Test03 {
	public static void main(String[] args) throws IOException {
			//D:\workspace\MyDay34\file01\file02\file03\qnz.txt
		File file = new File("file01\\file02\\file03\\qnz.txt");
		
		//获取父路径 -- D:\workspace\MyDay34\file01\file02\file03
		File parentFile = file.getParentFile();
		//判断父路径是否存在
		if(!parentFile.exists()){
			//创建多层目录
			parentFile.mkdirs();
		}
		
		//判断文件是否存在
		if(!file.exists()){
			//创建文件
			file.createNewFile();
		}
	}
}

需求3:

输出指定目录下的所有文件信息

public class Test01 {
	public static void main(String[] args) {
		
		File file = new File("D:\\笔记");
		
		//获取当前目录下所有文件及文件夹的名字
//		String[] list = file.list();
//		for (String fileName : list) {
//			System.out.println(fileName);
//		}
		
		//获取当前目录下所有的file对象
		File[] listFiles = file.listFiles();
		
		//获取当前目录下所有的文件及文件夹的file对象
		for (File f : listFiles) {
			System.out.println(f.getName() + " -- " + f.canRead() + " -- " + f.canWrite());
		}
		
	}
}
1)要求只输出文件后缀名为txt的文件
public class Test02 {
	public static void main(String[] args) {
		
		File file = new File("D:\\笔记");
		
		//获取当前目录下所有文件及文件夹的名字
//		String[] list = file.list();
//		for (String fileName : list) {
//			if(fileName.endsWith(".txt")){
//				System.out.println(fileName);
//			}
//		}
		
		//获取当前目录下所有的file对象
		File[] listFiles = file.listFiles();
		
		//获取当前目录下所有的文件及文件夹的file对象
		for (File f : listFiles) {
			
			String fileName = f.getName();
			
			//判断f是否是文件
			if(f.isFile() && fileName.endsWith(".txt")){
				System.out.println(fileName);
			}
		}
		
	}
}
2)根据API的过滤器来完成该功能
public class Test03 {
	public static void main(String[] args) {
		
		File file = new File("D:\\笔记");
		
		String[] list = file.list(new FilenameFilter() {
			@Override
			public boolean accept(File dir, String name) {
				
				File childFile = new File(dir, name);
				if(childFile.isFile() && childFile.getName().endsWith(".txt")){
					return true;
				}
				return false;
			}
		});
		
		for (String fileName : list) {
			System.out.println(fileName);
		}
		
	}
}
3)需求继续跟进,列出当前目录及子目录中符合该条件的文件信息(递归)

递归:方法里面调用方法自身

public class Test04 {
	public static void main(String[] args) {
		
		File file = new File("D:\\笔记");
		
		fileHandler(file, ".txt");
		
	}
	
	public static void fileHandler(File file,String suffix){
		
		File[] listFiles = file.listFiles();
		
		for (File f : listFiles) {
			if(f.isFile()){//文件
				
				String name = f.getName();
				if(name.endsWith(suffix)){
					System.out.println(name);
				}
				
			}else if(f.isDirectory()){//文件夹
				fileHandler(f, suffix);
			}
		}
	}
}

IO流

概念

IO流是计算机编程中的一个重要概念,主要用于处理数据的输入和输出操作。
I – in – 输入(读)

O – out – 输出(写)

流 – 一点一点的像水流一样去传输数据
注意:站在程序的角度去看待输入还是输出

分类

按照方向分流:输入流、输出流

按照单位分流:字节流、字符流

按照功能分流:基础流/节点流、处理流

注意:new 处理流(new 基础流) – 装饰者模型 – 处理流对象中往往包含了基础流的对象,在基础流的基础上拓展了额外的功能,使得流更为强大(效率),工作中一般使用处理流

存储单位

1024byte = 1KB

1024KB = 1MB

1024MB = 1GB

1024GB = 1TB

1024TB = 1PB
注意:进制1024

学习注意事项

  1. 按照流的发展历史去学习
  2. 注意流与流之间的继承关系
  3. 举一反三

字节流

应用场景:操作二进制数据(音频、视频、图片)

abstract class InputStream – 字节输入流的基类(抽象类)

abstract class OutputStream – 字节输出流的基类(抽象类)

class FileInputStream extends InputStream – 文件字节输入流

class FileOutputStream extends OutputStream – 文件字节输出流

class FilterInputStream extends InputStream – 过滤器字节输入流

class FilterOutputStream extends OutputStream – 过滤器字节输出流

class BufferedInputStream extends FilterInputStream – 带缓冲区的字节输入流

class BufferedOutputStream extends FilterOutputStream – 带缓冲区的字节输出流

默认缓冲区大小:8192字节

1.利用 文件字节输出流 向文件写入数据

  1. 不处理异常

  2. 当文件存在时

  3. 当文件不存在时

经验:所有的输出流,当文件不存在时都会创建该文件

public class Test01 {
	public static void main(String[] args) throws IOException {
		
		//1.创建流对象
		FileOutputStream fos = new FileOutputStream("io.txt");
		
		//2.写入数据
		//fos.write(97);//写入UniCode码
		//fos.write("123abc".getBytes());//写入byte数组
		fos.write("123abc".getBytes(), 2, 3);//写入byte数组、偏移量、写入长度
        //3ab
        
		//3.关闭资源
		fos.close();
		
	}
}
  1. 在文件末尾追加内容

经验:在文件末尾追加考虑基础流的构造方法

public class Test02 {
	public static void main(String[] args) throws IOException {
		
		//1.创建流对象 + 设置在文件末尾追加
		FileOutputStream fos = new FileOutputStream("io.txt",true);//默认是false
		//2.写入数据
		fos.write("123abc".getBytes());//写入byte数组
		//3.关闭资源
		fos.close();
	}
}
  1. 处理异常
public class Test03 {
	public static void main(String[] args) {
		
		FileOutputStream fos = null;
		try {
			//1.创建流对象 + 设置在文件末尾追加
			fos = new FileOutputStream("io.txt",true);
			
			//2.写入数据
			fos.write("123abc".getBytes());//写入byte数组
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			
			//3.关闭资源
			if(fos != null){
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
			
	}
}

注意:

对于try-catch,底层会逐句判断,所有在同样功能情况下,try中代码越少越好

2.利用 文件字节输入流 读取文件里的数据

注意:

读取中文数据时会出现中文乱码的情况

utf-8编码1个中文占3个字节,gbk编码1个中文占2个字节

读取中文数据采用的是一次读取一个字节的方式,始终会报错

只能使用每次读取一个字节数组的方式来读取

  1. 不处理异常
  2. 文件存在
public class Test04 {

	public static void main(String[] args) throws IOException {
		
		//1.创建流对象
		FileInputStream fis = new FileInputStream("io.txt");
		
		//2.读取数据
		//read():一个字节一个字节的读取数据,读取到文件末尾返回-1
		int read = fis.read();
		System.out.println(read);
		read = fis.read();
		System.out.println(read);
		read = fis.read();
		System.out.println(read);
		read = fis.read();
		System.out.println(read);
		read = fis.read();
		System.out.println(read);
		read = fis.read();
		System.out.println(read);
		read = fis.read();
		System.out.println(read);
		
		//3.关闭资源
		fis.close();
	}
}

减少冗余代码,但还是一个字节一个字节的读取数据

//while循环读取		
		//2.读取数据
		//read():一个字节一个字节的读取数据,读取到文件末尾返回-1
		int read;
		while((read = fis.read()) != -1){
			System.out.println((char)read);
		}	

加快读取

//指定长度读取
		//2.读取数据
		//read(bs):读取bs长度的数据,并把数据放入数组,返回读取到的有效字节数,如果读取到文件末尾则返回-1
		byte[] bs = new byte[1024];
		int len;
		while((len = fis.read(bs)) != -1){
			System.out.println(new String(bs, 0, len));
		}
  1. 文件不存在

经验:所有文件输入流,在文件不存在的情况下都会报错 – FileNotFoundException

  1. 处理异常
public class Test07 {
	public static void main(String[] args){
			
		FileInputStream fis = null;
		try {
			//1.创建流对象
			fis = new FileInputStream("io.txt");
			
			//2.读取数据
			//read(bs):读取bs长度的数据,并把数据放入数组,返回读取到的有效字节数,如果读取到文件末尾则返回-1
			byte[] bs = new byte[1024];
			int len;
			while((len = fis.read(bs)) != -1){
				System.out.println(new String(bs, 0, len));
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//3.关闭资源
			if(fis != null){
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}	
	}
}

文件拷贝

利用文件字节输入、输出流

思路:读取源文件,写入目标文件

public class Copy01 {
	public static void main(String[] args) throws IOException {
		
		FileInputStream fis = new FileInputStream("奇男子.mp4");
		FileOutputStream fos = new FileOutputStream("copy.mp4");
		
		int read;
		while((read = fis.read()) != -1){
			fos.write(read);
		}
		
		fis.close();
		fos.close();
	}
}

加快拷贝,数据大的时候就很明显

		byte[] bs = new byte[1024];
		int len;
		while((len = fis.read(bs)) != -1){
			fos.write(bs, 0, len);
		}

处理异常

public class Copy03 {
	public static void main(String[] args){
		
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try {
			fis = new FileInputStream("奇男子.mp4");
			fos = new FileOutputStream("copy.mp4");
			
			byte[] bs = new byte[1024];
			int len;
			while((len = fis.read(bs)) != -1){
				fos.write(bs, 0, len);
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//分开关闭,不然会出问题if(fis != null && fos != null)导致无法关闭
			if(fis != null){
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			
			if(fos != null){
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

简化,新特性

public class Copy04 {
	public static void main(String[] args){
		
		//注意:小括号里创建的流会在try...catch后自动关闭
		try(FileInputStream fis = new FileInputStream("奇男子.mp4");
				FileOutputStream fos = new FileOutputStream("copy.mp4");) {
			
			byte[] bs = new byte[1024];
			int len;
			while((len = fis.read(bs)) != -1){
				fos.write(bs, 0, len);
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
  • 20
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值