第十章_IO流

一、File 文件类

封装一个磁盘路径字符串,对这个路径可以执行一次操作。
可以用来封装文件路径、文件夹路径、不存在的路径。

1、创建对象

new File(路径);

File file = new File("E:\\abc\\1.txt");

2、 常用方法

   
文件、文件夹属性
			file.length():文件的字节量、长度
			file.exists():是否存在,存在返回 true
	 		file.isFile():是否为文件,是文件返回 true
			file.isDirectory():是否为文件夹,是文件夹返回true
			file.getName():获取文件/文件夹名
			file.getParent():获取上一级目录的路径
			file.getAbsolutePath():获取文件的绝对路径
			
创建、删除.
			file.createNewFile():新建文件,文件已经存在返回false
			file.mkdirs():新建多层文件夹\a\b\c
			file.mkdir():新建单层文件夹\a
			file.delete():删除文件,删除空文件夹
			
文件夹列表.
			list):返回String[],包含文件名
			listFiles():返回 Filel[],包含文件对象

实战练习

	public static void main(String[] args) throws IOException {
		//1.创建文件对象
		//参数是具体的路径,这个路经可以是文件路径也可以是文件夹路径
		File file = new File("G:\\abc\\1.txt");
		
		//2、测试常用方法
		// 文件、文件共属性
		 System.out.println(file.length());//14	文件的字节量
		 System.out.println(file.exists());//true	是否存在
		 System.out.println(file.isFile());//true	是否为文件
		 System.out.println(file.isDirectory());//false	是否为文件夹
		 System.out.println(file.getName());//1.txt	获取文件/文件夹名
		 System.out.println(file.getParent());//G:\abc	获取上一级的路径
		 System.out.println(file.getAbsolutePath());//获取文件的绝对路径
		 
		 
		 
		 //3、创建、删除
		 file = new File("G:\\abc\\2.txt");
		System.out.println( file.createNewFile());//新建文件2.txt
		
		file = new File("G:\\abc\\M");
		System.out.println( file.mkdir());//新建单层不存在的文件夹\M
		
		file = new File("G:\\abc\\O\\P\\Q");
		System.out.println( file.mkdirs());//新建多层不存在的文件夹O\\P\\Q
		
		System.out.println( file.delete());//删除文件,删除空文件夹
		

		
		//4、文件夹列表
		file = new File("G:\\abc\\M");
		String[] names = file.list();
		//列出文件夹中的所有文件的名称
		System.out.println(Arrays.toString(names));
		
		File[] fs = file.listFiles();
		//列出文件夹中的所有文件的文件对象
		System.out.println(Arrays.toString(fs));
}

3、递归求目录总大小

//递归求目录总大小
	public static void main(String[] args) {
		//1.指定求哪个目录的总大小
		File f=new File("G:\\a\\b");
		
		//2.调用size方法 求目录大小
		long l=size(f);//将这个目录传递给size方法,放到L中
		System.out.println(l);
	}

	private static long size(File f) {
		//1.列出目录下的所有资源listFiles();
		File[] ls = f.listFiles();
		long sum=0;
		//2.遍历数组获取每个文件对象
		for (int i = 0; i < ls.length; i++) {
			File f1=ls[i];//ls[i]就是遍历到的每个文件对象啊
			
		//3.拿到文件对象要判断啊
			if (f1.isFile()) {//isFile()判断刚刚遍历的对象是不是文件
				//是文件求文件字节量的大小
				sum=f1.length()+sum;
			}else if (f1.isDirectory()) {//isDirectory()判断刚刚遍历的对象是不是文件夹
				//如果是文件夹,那就继续做刚刚相同的业务--方法的递归
				sum=size(f1)+sum;
			} 
		}
		return sum;//把sum记录的值返回调用位置
	}

4、递归删除文件

	//递归删除文件夹
	public static void main(String[] args) {
		//1.指定想要删除的文件
		File f=new File("G:\\a\\b");
		del(f);//通过del方法完成业务
	}

	private static void del(File f) {
		//1.列出文件下的所有资源listFlies()
		File[] ls = f.listFiles();
		
		//2遍历到每个资源,然后进行判断是否为空文件,或非空文件
		for (int i = 0; i < ls.length; i++) {
			File f1 = ls[i];//ls[i]就是遍历的每个文件
			
			//3判断当前资源是文件夹还是文件
			if (f1.isFile()) {
				
				f1.delete();//是文件直接删除即可呀
				
			}else if(f1.isDirectory()) {
				//是文件夹的话,继续做刚刚相同的业务---方法的递归
				del(f1);
			}
		}//4最后删除f文件即可(因为里面已经没有资源了--是空的)
			f.delete();
	}
}

二、IO字节流

java.io包:

字节流:针对二进制文件

一、 InputStream 字节流的读取流

是个抽象父类,不能创建对象,无法直接使用read()进行读取

(1、)FilelnputStream

InputStream的普通子类,创建子类对象使用read()进行文件的读取

private static void method() {
	try {
1.创建字节流的读取对象
//InputStream是字节读取流的父类,是抽象类,不能new
//InputStream in=new InputStream() ;报错

InputStream in=new FileInputStream(new File("G://a//1.txt"));
InputStream in2=new FileInputStream("G://a//1.txt");
//这里创建对象右两种方式,一种是传入一个File形式,一种是String形式

2.开始读取,read()读取不到字节时会返回-1
	
			int b;//定义变量记录读取到的数据
			while ( (b = in.read()) != -1) {//有数据就一直读
				System.out.println(b);
			}
			
3.释放资源
		in.close();
		} catch (IOException e) {
			e.printStackTrace();
(2、)BufferedInputStream

InputStream的高效读子类,创建子类对象使用read()进行文件的读取

new BufferedInputStream(new FilelnputStream(D://****”))
(3、)ObjectInputStream

对象读取流,可以直接创建对象

二、OutputStream 字节流的写出流

是个抽象父类不能创建对象,无法直接使用write()进行写出

测试字节的写出OutputStream
	//测试字节输出流
	public static void main(String[] args)  {
		method();//使用普通的字节输出流对象输出数据FileOutputStream
}

	private static void method() {
		FileOutputStream out2 = null;//声明变量,因为finally要用
		try {
	//1.创建输出流对象。两种方式
	//OutputStream out=new FileOutputStream(new File("G:\\abc\\2.txt"));
	out2=new FileOutputStream("G:\\abc\\2.txt");
			
			//2.利用OutputStream里的方法进行写出数据
			out2.write(97);

		} catch (IOException e) {
			e.printStackTrace();
		}finally {//保证代码一定会被执行,一定要放到finally里
try {
	//3.释放资源
				out2.close();
			} catch (IOException e) {
				e.printStackTrace();
			}		
(1、)FileOutputStream

OutputStream的普通子类,创建子类对象使用write()进行写出

(2、)BufferedOutputStream

OutputStream的高效写子类,创建子类对象使用write()进行写出

new BufferedOutputStream(new FileOutputStream(D://****”),true)

效率问题:

为什么BufferedOutputStream > FiledOutputStream
因为:BufferedOutputStream底层维护了一个byte[ ],默认容量是8*1024字节,8K
不管是读取流还是写出流,Buffered底层维护了:---效率高
字符是char [ ]---------字节是byte[ ]
(3、)ObjectOutputStream

对象输出流,可以直接创建对象

三、IO字符流

字符流:针对文本文件
读写容易发生乱码现象,在读写时最好指定编码集为utf-8

一、Reader 字符读取流

是个抽象父类,不能创建对象,就无法直接使用read()进行读取

(1、)FileReader

Reader的子类,创建子类对象使用read()进行文件的读取

测试字符的读取Reader
	//测试字符流的读取
	public static void main(String[] args) throws IOException {
	method();
	method2();//高效字符流读取,
}


private static void method2() throws IOException {
	Reader in3=new BufferedReader(new FileReader("D://a//c.txt"));
	//BufferedReader是高效的读取对象,
	//原因在于底层维护了一个char[],默认容量是8*1024	字节,就是8k

	//以下操作和method()一样
	}

	private static void method() {
	try {
		//1.创建对象
        //Reader in=new Reader(); 
        //Reader是字符流读取对象的父类,但是是一个抽象类,不能new
			Reader in=new FileReader(new File("D://a//c.txt"));
			Reader in2=new FileReader("D://a//c.txt");
			
		//2.开始读取
		//定义一个变量记录读取的数据
			int b;
			while ( (b=in.read()) != -1 ) {//只要有数据就一直读
				System.out.println(b);
				
			}
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
(2、)BufferedReader

Reader的高效子类,创建子类对象使用read()进行文件的读取

(3、)InputStreamReader

Reader的子类,创建子类对象使用read()进行文件的读取

二、Writer字符写出流

是个抽象父类不能创建对象,无法直接使用write()进行写出

测试字符输出流数据

	//测试字符输出流数据--普通FileWriter
public static void main(String[] args) throws IOException{
	Writer out =new FileWriter("D://a//t.txt",true);
		out.write("hello");
		out.write("java");
		out.write(100);
		out.close();
}

	//测试字符输出流数据--高效BufferedWriter
public static void main(String[] args) throws IOException{
	Writer out =new BufferedWriter(new FileWriter("D://a//t.txt",true));
		out.write("hello");
		out.write("java");
		out.write(100);
		out.close();
}
(1、)FileWriter

Writer的普通子类,创建子类对象使用read()进行文件的读取

(2、)BufferedWriter

Writer的普通子类,创建子类对象使用write()进行写出

(3、)InputStreamWriter

Writer的普通子类,创建子类对象使用read()进行文件的读取

读或写结束后一定要释放资源.close();

小结:

1.我们在io操作中会有大量的异常需要捕获,
2.字节读取(InputStream),利用子类创建对象,
其中又分普通子类	FileInputStream和高效BufferedIntputStream,
写出是OutputStream

3.字符读取(Reader),利用子类创建对象,
其中又分普通子类	FileReader和高效BufferedReader,写出是Write

4.在字节(OutputStream)、字符(Writer),写出时,
如果不想覆盖掉之前的数据,在创建对象时需要给出两个参数,
一个是文件的地址,一个是true

文件的复制案例----这里展示的是字符流

文件的复制案例----这里展示的是字符流
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.Scanner;

public class J {
	//测试文件复制
	public static void main(String[] args){
		//开发思路:读取到源文件,写出到目标文件中
		System.out.println("请输入源文件路径");
		String f=new Scanner(System.in).nextLine();
		File form=new File(f);
		
		System.out.println("请输入目标路径");
		String t=new Scanner(System.in).nextLine();
		File to=new File(t);
		
		copy(form,to);
	}

	private static void copy(File form, File to) {
		Reader in=null;
		Writer out=null;
		try {
		//1.读取form文件
			 in =new BufferedReader(new FileReader(form));
			
		//2.写出到to文件
			 out =new BufferedWriter(new FileWriter(to));
			
		//边读边写
			int b;//定义变量,记录读取到的数据
			while ((b=in.read()) != -1) {
				out.write(b);//把b读到的资源写入out中	
			}
			System.out.println("复制成功");
			
		} catch (IOException e) {
			System.out.println("复制失败");
			e.printStackTrace();
		}finally {
			try {
				//3.释放资源
				in.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			try {
				//3.释放资源
				out.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		

序列化、反序列化

序列化(Serialization):
将对象的状态信息转换为可以存储或传输的形式过程
把java中的一个对象存储起来,放在一个磁盘中,是一个写出的动作–out

序列化
利用ObjectOutputStream,对象的信息,按固定格式转成一串字节值输出并持久保存到磁盘化

反序列化: 利用ObjectInputStrean,读取磁盘中序列化数据,重新恢复对象

序列化/反序列化的特点-应用场景:
1.需要序列化的文件必须实现Serilizable接口 以启用其序列化功能
2.不需要序列化的数据可以被修饰为static的,由于static属于类,不随对象被序列化输出
3.不需要序列化的数据也可以修饰为transient 临时的,只在程序运行期间,在内存中存在不会被序列化持久保存
4.在反序列化时,如果和序列化的版本号不一致,无法完成反序列化
5.每个被序列化的文件都有一个唯一id,如果没有添加编译器会根据类的定义信息计算生一个版本号
6.常用于服务器之间的数据传输,序列化成文件,反序列化读取数据。
7.常用于使用套接字流在主机之间传递对象

案例:

//测试序列化ObjectOutputStream
	//序列化:是指把程序中的java对象永久保存在磁盘中  相当于是写出的过程,out---ObjectOutputStream
	public static void main(String[] args){
	try {
		//1.创建序列化对象ObjectOutputStream
			ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("G:\\a\\1.tet"));
			
		//2.指定要输入的对象
			Student obj = new Student("jack",20,"北京");
			out.writeObject(obj);
			
		System.out.println("序列化完成");	
		} catch (IOException e) {
		System.out.println("序列化失败");
			e.printStackTrace();
		}
	
//这个类用来描述学生类
//这个文件想要完成序列化必须实现可序列化接口,否则报错
public class Student implements Serializable{
		
	/**
	 *给这个文件分配唯一的id值 
	 */
	private static final long serialVersionUID = 1L;

	private String name;
	private int age;
	private String addr;

//提供构造方法--右键Source-倒数第三个-ok	
	//提供公共的访问权限--重写get()...set()...

总结:
序列化就是通过java程序将对象里的值写出到磁盘中保存
1.文件想要完成序列化必须实现可序列化接口implements Serializable,实现后可以给这个文件分配唯一的id值

2.在main方法中.创建序列化对象ObjectOutputStream
ObjectOutputStream创建对象时,它的参数是它的子类new FileOutputStream(“G:\a\1.tet”)

3.然后指定要输入的对象,指定对象是ObjectOutputStream的一个方法writeObject(obj)
指定对象前,没有对象要创建对象
Student obj = new Student(“jack”,20,“北京”);
out.writeObject(obj);将obj写出到out里

案例:

	//测试反序列化ObjectInputStream
	//反序列化:是指把已经序列化好的文件保存的数据,读取/恢复到java程序的过程,in---ObjectInputStream
	public static void main(String[] args){
		try {
		//1.创建反序列化对象ObjectInputStream
		ObjectInputStream in=new ObjectInputStream(new FileInputStream("G:\\a\\1.tet"));
		
		//2.开始读取
		Object o = in.readObject();
		System.out.println(o);//默认打印了对象的地址值,是用了Object提供的toStrig(),需要在要读取的类里重写toString()
		
		
		
		
		System.out.println("反序列化完成");	
		
		in.close();//释放资源

	} catch (IOException e) {
		System.out.println("反序列化失败");
		e.printStackTrace();
	}



//这个类用来描述学生类
//这个文件想要完成反序列化必须实现可序列化接口,否则报错
public class Student implements Serializable{
	
	/**
	 *给这个文件分配唯一的id值 
	 */
	private static final long serialVersionUID = 1L;

	//提供构造方法--右键Source-倒数第三个-ok
//提供公共的访问权限--重写get()...set()...
	//重写toString()
	
	private String name;
	private int age;
	private String addr;






总结:反序列化是指把已经序列化好的文件保存的数据,读取/恢复到java程序的过程,in---ObjectInputStream
1.文件想要完成反序列化必须实现可序列化接口implements Serializable,实现后可以给这个文件分配唯一的id值 

2.在main方法中.创建反序列化对象ObjectInputStream
ObjectInputStream创建对象时,它的参数是它的子类new FileInputStream("G:\\a\\1.tet")

3.然后就可以读取了,读取方法是ObjectInputStream的一个方法readObject()返回值是一个Object对象
			Object o = in.readObject();
4.然后直接打印o就可以了,这里注意默认打印了对象的地址值,是用了Object提供的toStrig(),需要在要读取的类里重写toString()

		

编码转换流
用来作为桥梁,把字节流转成字符流
用来解决字符流读写乱码问题

工具类:
		OutputStreamWriter:是字节流转向字符流的桥梁 
		OutputStreamWriter(OutputStream out,String charsetName)
		OutputStreamWriter(OutputStream out)
		
		InputStreamReader:是字节流通向字符流的桥梁 
		InputStreamReader(InputStream in)

案例;
	//测试编码转换流
	public static void main(String[] args){
	try {
		//测试写出的编码转换流:OutputStreamWriter,用来把字节流转成字符流
		//1.创建OutputstreamWriter对象

			OutputStreamWriter out=new OutputStreamWriter(new FileOutputStream("1.txt"),"gbk");

			//txt不是磁盘的路径,就会在同级src下创建(需要按f5刷新出来)
			//默认编码是gbk,也可以传入两个参数,第二个参数可以指定编码集
		//2.写出数据
			out.write("abc");
			
			
		//3.释放资源	
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

如青春如烈火

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值