Java—IO

一、什么是IO流

流是一种抽象概念,它代表了数据的无结构化传递。按照流的方式进行输入输出,数据被当成无结构的字节序或字符序列。从流中取得数据的操作称为提取操作,而向流中添加数据的操作称为插入操作。用来进行输入输出操作的流就称为IO流。换句话说,IO流就是以流的方式进行输入输出。

使用流有两个操作:

  • 向流中添加数据

  • 从流中取得数据

在这里插入图片描述

二、IO流的分类

1、按照流向分

  • 输入流

    读入内存中

  • 输出流

    流出内存写出的流

2、按照操作数据的最小的单位

  • 字节流

    每个字节每个字节的读,每个字节每个字节的写

    每读写一次都是一个字节

  • 字符流

    每读写一次都是一个字符

3、按照功能分

  • 节点流

    直接跟输入输出源对接

  • 处理流

    建立在低级流的基础上,对接的是节点流

    处理流的目的是更加方便,高效的进行数据读写操作

三、常用的IO流

字节操作相关的流

InputStream(输入流、字节流)

  • FileInputStream(文件输入字节流 - 节点流)
  • BufferedInputStream(缓冲流 )
  • ObjectInputStream(对象输入字节流 - 处理流)
  • ByteArrayInputStream(字节数组输入流[内存流] - 用它来缓存数据)
  • DataInputStream(读取Java基本类型的数据)

OutputStream(输出流、字节流)

  • FileOutputStream
  • BufferedOutputStream
  • ObjectOutputStream
  • ByteArrayOutputStream
  • DataOutputStream

字符操作相关的流

Reader(输入流、字符流)

  • FileReader(文件输入字符流)
  • BufferedReader(缓冲流 - 缓冲的是字符)
  • InputStreamReader(字符流 - 转换流 - 将字符流转为字节流)

Writer(输出流、字符流)

  • FileWriter
  • BufferedWriter
  • OutputStreamWriter(字符输出流- 转换流 - 将字符输出流转为字节输出流)

1、文件操作

(1)读取文件内容(文本文件)

  • 选流

    • 输入流

    • 字节流/字符流

      InputStream/Reader

    • 操作文件的

      FileInputStream/FileReader

  • 文件字节输入流

    未关流:

在这里插入图片描述

public class FileInputStreamTest {

	public static void main(String[] args) {
		
		InputStream in = null;
		try {
			//1、创建输入流对象
//			InputStream in = new FileInputStream("D:/bbb/test.txt");
			in = new FileInputStream(new File("D:/bbb/test.txt"));
			//2、调用方法读取
			//如果我们想读取文件所有的内容,肯定要使用循环,结束循环的条件是最后读到的值为-1
			int i;
			while((i = in.read()) != -1) {
				System.out.println(i);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//3、关闭流
			try {
				if(in != null) {
					in.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}
	
}

我们使用字节流读文本文件,如果文本文件出现中文等特殊字符,会导致读取乱码

读取文件内容,我们建议使用字符流,字符是一个字符一个字符的读

  • 文件字符输入流

    public class FileReaderTest {
    
    	public static void main(String[] args) {
    		Reader reader = null;
    		try {
    			//1、创建流对象
    			reader = new FileReader("D:/bbb/test.txt");
    			//2、循环读
    			int i;
    			while((i = reader.read()) != -1) {
    				System.out.println((char)i);
    			}
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			//3、关闭流
    			try {
    				if(reader != null) {
    					reader.close();
    				}
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    		
    		
    	}
    	
    }
    
  • 字符流 - 一行一行的读

    BufferedReader

    package com.qjzx._06_bufferedreader;
    
    import java.io.BufferedReader;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.Reader;
    import java.util.ArrayList;
    import java.util.List;
    
    public class BufferedReaderTest {
    
    	public static void main(String[] args) {
    		
    		List<Student> list = new ArrayList<>();
    		
    		try(
    			Reader reader = new FileReader("F:\\课程资料\\2021-06-15-IO\\doc\\练习.txt");
    			BufferedReader br = new BufferedReader(reader);
    		){
    			//行数据
    			String line;
    			br.readLine();//先读一行
    			while((line = br.readLine()) != null) {
    				//line = "1,张三,18,男";
    				String[] split = line.split(",");//["1","张三","18","男"]
    				Student st = new Student(Integer.parseInt(split[0]),split[1],Integer.parseInt(split[2]),split[3]);
    				list.add(st);
    			}
    			
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		
    		
    		System.out.println(list);
    		
    		
    	}
    	
    }
    
    class Student{
    	private int id;
    	private String name;
    	private int age;
    	private String gender;
    	
    	public Student() {}
    	
    	public Student(int id, String name, int age, String gender) {
    		super();
    		this.id = id;
    		this.name = name;
    		this.age = age;
    		this.gender = gender;
    	}
    	public int getId() {
    		return id;
    	}
    	public void setId(int id) {
    		this.id = id;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public int getAge() {
    		return age;
    	}
    	public void setAge(int age) {
    		this.age = age;
    	}
    	public String getGender() {
    		return gender;
    	}
    	public void setGender(String gender) {
    		this.gender = gender;
    	}
    
    	@Override
    	public String toString() {
    		return "Student [id=" + id + ", name=" + name + ", age=" + age + ", gender=" + gender + "]";
    	}
    	
    	
    	
    }
    
    

(2)数据写入文件

  • 字节操作

    package com.qjzx._03_fileoutputstream;
    
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    
    /**
     * 
     * 1、创建FileOutputStream对象
     * 		FileOutputStream(File file) 
     * 			覆盖
     * 		FileOutputStream(File file, boolean append) 
     * 			true 追加内容  false 覆盖内容(先清空之前的内容)
     * 		FileOutputStream(String name) 
     * 		FileOutputStream(String name, boolean append) 
     * 2、调用方法进行写操作
     * 3、关闭流
     * 
     * @author Administrator
     *
     */
    public class FileOutputStreamTest {
    
    	public static void main(String[] args) {
    		
    		/**
    		 * try后面的()中可以创建流的对象
    		 * 流在使用结束后自动关闭
    		 * 前提是流实现Closeable接口
    		 */
    		try (OutputStream out = new FileOutputStream("D:/bbb/test.txt",true)){
    			
    			out.write('D');
    			out.write('D');
    			out.write('D');
    			out.write('D');
    			out.write('D');
    			out.write('我');
    			
    			
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		
    		
    		
    	}
    	
    }
    
    
  • 字符操作

    public class FileWriterTest {
    
    	public static void main(String[] args) {
    		
    		try(FileWriter writer = new FileWriter("D:/bbb/test.txt",true)){
    			
    			writer.write('我');
    			writer.write('是');
    			writer.write('中');
    			writer.write('国');
    			writer.write('人');
    			writer.write("我爱中国");
    			
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		
    	}
    	
    }
    
  • 一行一行的写

    BufferedWriter

    newLine() 跨平台换行

    public class BufferedWriterTest {
    
    	public static void main(String[] args) {
    		
    		//准备数据
    		/*
    		List<Student> list = new ArrayList<>();
    		list.add(new Student(4,"赵六",21,"男"));
    		list.add(new Student(5,"田七",25,"女"));
    		*/
    		List<Student> list = Arrays.asList(
    								new Student(4,"赵六",21,"男"),
    								new Student(5,"田七",25,"女"));
    		
    		try(
    			Writer writer = new FileWriter("F:\\课程资料\\2021-06-15-IO\\doc\\练习.txt",true);
    			BufferedWriter bw = new BufferedWriter(writer);
    		){
    			
    			//先换个行
    			bw.newLine();
    			//写
    			for (Student student : list) {
    				
    				bw.write(student.toString());
    				//写完之后换行
    				bw.newLine();
    				
    			}
    			
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		
    		
    		
    	}
    	
    }
    

(3)文件的复制

/**
 * 如何提高效率?
 * 	read(byte[] bytes)这个方法
 * 	一次读多个字节
 * @author Administrator
 *
 */
public class FileCopyPlus {

	public static void main(String[] args) {
		
		try(
			InputStream in = new FileInputStream("F:\\课程资料\\2021-05-24-Java概述与环境搭建\\video\\01_计划安排.mp4");
			OutputStream out = new FileOutputStream("D:/abc.mp4");
		){
			
			byte[] buffer = new byte[1024];
			int length;
			
			//读
			while((length = in.read(buffer)) != -1) {
				//写,buffer缓冲的字节数组,0 从buffer的那个位置开始写,length 写几个(读几个就写几个)
				out.write(buffer,0,length);
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	
}

(4)文件的剪切

  • 先复制,再删除

2、对象操作

ObjectInputStream 反序列化

ObjectOutputStream 序列化

可以序列化的对象必须实现 Serializable接口

  • 对象的持久化
public class ObjectDurableTest {

	public static void main(String[] args) {
		
		Student st = new Student(1,"张三",19,"女");
		
		try(
			OutputStream out = new FileOutputStream("d:/student.obj");
			ObjectOutputStream objOut = new ObjectOutputStream(out);
		){
			//将java对象写入到流中保存到其他地方,序列化
			//可以被序列化的对象必须实现Serializable接口
			objOut.writeObject(st);//java.io.NotSerializableException
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	
}
  • 对象的反序列化
public class ObjectInputStreamTest {
	
	public static void main(String[] args) {
		
		try(
			InputStream in = new FileInputStream("d:/student.obj");
			ObjectInputStream objIn = new ObjectInputStream(in);
		){
			
			Object object = objIn.readObject();
			//反序列化,通过流读取数据加载到内存中,创建java对象
			Student st = (Student) object;//创建了一个对象
			System.out.println(st);
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
	}
	

}
  • 集合的序列化与反序列化
public class ListSeralizableTest {

	public static void main(String[] args) {
		
		/*
		 * 序列化
		List<Student> list = Arrays.asList(
				new Student(4,"赵六",21,"男"),
				new Student(5,"田七",25,"女"));
		
		try(
				OutputStream out = new FileOutputStream("d:/students.obj");
				ObjectOutputStream objOut = new ObjectOutputStream(out);
		){
			
			objOut.writeObject(list);
		
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		*/
		
		
		try(
			InputStream in = new FileInputStream("d:/students.obj");
			ObjectInputStream objIn = new ObjectInputStream(in);
		){
			
			Object object = objIn.readObject();
			List<Student> list = (List<Student>) object;//创建了一个对象
			System.out.println(list);
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
			
	}
	
}

四、流的选择

文件内容操作的时候

FileInputStream/FileOutputStream

FileReader/FileWriter

ObjectInputStream/ObjectOutputStream

BufferedReader/BufferedRWriter

File…操作文件

Object…操作对象

Buffered…缓冲

如果我们只是简单的读写

InputStream/OutputStream

Reader/Writer

流向的判断:内存!!!!

  • 先判断流向
  • 选择操作的单位
  • 数据源
  • 处理 - 处理流

= (List) object;//创建了一个对象
System.out.println(list);

	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	} catch (ClassNotFoundException e) {
		e.printStackTrace();
	}
		
}

}




# 四、流的选择

文件内容操作的时候

FileInputStream/FileOutputStream

FileReader/FileWriter

ObjectInputStream/ObjectOutputStream

BufferedReader/BufferedRWriter


File.....操作文件

Object....操作对象

Buffered....缓冲

如果我们只是简单的读写

InputStream/OutputStream

Reader/Writer

流向的判断:内存!!!!

- 先判断流向
- 选择操作的单位
- 数据源
- 处理 - 处理流





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值