10.19-IO流
流根据功能可以划分为输入流与输出流
输入流:用于读取数据
输出流:用于写出数据
输入输出流的参照对象是基于我们的程序而言的
流的划分
基于处理单位
字节流:以字节为单位读写数据
字符流:以字符为单位读写数据
基于级别
高级流:不能独立的存在,必须基于另外一个流工作
低级流:数据有明确的来源或去向
字节输入输出流的父类
InputStream 字节输入流的父类
OutputStream 字节输出流的父类
FIS/FOS 用于读写文件的流
FileInputStream
:文件字节输入流
例子-FileInputStream
FileInputStream
package day10_19;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
/**
* 文件字节输入流
*/
public class FileInputStreamDemo01 {
public static void main(String[] args) throws Exception {
/*
* FileInputStream(File file)
* FileInputStream(String fileName)
* 基于给定的文件名创建用于读写文件的输入流
*/
FileInputStream fis =
new FileInputStream("fos.dat");
/*
* int read()
* 读取一个字节,并以int值的形式返回
* 低八位有效,若返回-1,则EOF
*/
System.out.println((char)fis.read());
/*
* int read(byte[] b)
* 一次性尝试最多读取给定字节数组长度的字节,并将读取到的结果存入到给定的字节数组中
* 返回值为实际读取到的字节量
*/
byte[] array=new byte[100];
int len = fis.read(array);
System.out.println(len);
//反序列化(解码)
// String str = new String(array, "UTF-8");
// System.out.println(str);
//String(byte[] b,int start,int len,String CS)
String str = new String(array, 0, len, "UTF-8");
System.out.println(str);
fis.close();
}
}
FileOutputStream
:文件字节输出流
例子-FileOutputStream
FileOutputStream
package day10_19;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
/**
* 文件字节输出流
*/
public class FileOutputStreamDemo01 {
public static void main(String[] args) throws Exception {
/*
* FileOutputStream(File file)
* FileOutputStream(String fileName)
* 基于给定的文件名创建用于写文件的输出流
*/
FileOutputStream fos = new FileOutputStream("fos.dat");
/*
* void write(int d)
* 写出一个字节,写出给定int值的低八位
*/
fos.write('A');
/*
* void write(byte[] b)
* 将给定字节数组中所有的字节一次性全部写出
*/
String str="你好啊";
byte[] data=str.getBytes("UTF-8");
fos.write(data);
/*
* void write(byte[] b,int start,int len)
* 将给定的字节数组中从start处开始,连续将len个字节输出
*/
//关闭流
fos.close();
}
}
例子-注意事项
package day10_19;
import java.io.FileOutputStream;
/**
* 文件字节输出流
*/
public class FileOutputStreamDemo02{
public static void main(String[] args) throws Exception {
// FileOutputStream fos =
// new FileOutputStream("fos.dat");
// //当重新写入内容时,该文件原先内容会被废弃
// fos.write('B');
// fos.close();
/*
* FileOutputStream(File file,boolean append)
* FileOutputStream(String fileName,boolean append)
* 基于给定的文件名创建用于写文件的输出流
* 在当前文件上追加写操作
*/
FileOutputStream fos =
new FileOutputStream("fos.dat", true);
fos.write('C');
fos.close();
}
}
BIS/BOS 高级流
BufferedInputStream : 缓存字节输入流
BufferedOutputSteam :缓存字节输出流
高级流:会带一些额外的功能
例子-BufferedOutputSteam
package day10_19;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
public class BufferedOutputSteamDemo01 {
/**
* 高级流不能独立工作,必须基于另外一个流
* 缓存流的功能:
* 内部维护了一个缓存区,用于减少读写次数,提高读写效率
* @throws Exception
*/
public static void main(String[] args) throws Exception {
FileOutputStream fos =
new FileOutputStream("bos.txt");
BufferedOutputStream bos = //自带一个8KB缓存
new BufferedOutputStream(fos);
//序列化
String str = "大家好";
byte[] data = str.getBytes("UTF-8");
bos.write(data);
/*
* 当我们通过缓存字节输出流写出数据之后,
* 如果没有关闭流,数据仍会保存在缓存中,只有在流关闭/刷新后数据才会写入
* 在关闭流的时候,我们只需要关闭最外层的高级流即可,
* 因为高级流关闭自身之前要先将其处理流关闭后才能关闭自身。
*/
// bos.close();
bos.flush();//将缓存区数据刷新到文件中
}
}
DIS/DOS 高级流
DataInputStream:可以方便读取基本类型的数据
DataOutputStream:可以方便写出基本类型数据
例子-DataOutputStream
package day10_19;
import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class DataInputStreamDemo {
public static void main(String[] args) throws Exception {
/**
* DOS
* 该高级流带来的额外功能是方便我们写出基本类型
*/
FileOutputStream fos =
new FileOutputStream("dos.dat");
DataOutputStream dos =
new DataOutputStream(fos);
dos.writeInt(123);//4
dos.writeLong(123L);//8
dos.writeDouble(12.34);//8
dos.writeUTF("你好");//6+2
dos.close();
}
}
例子-DataInputStream
package day10_19;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class DataInputStreamDemo {
/**
* DIS:方便我们读取基本类型的数据
* @throws Exception
*/
public static void main(String[] args) throws Exception {
FileInputStream fis =
new FileInputStream("dos.dat");
DataInputStream dis = new DataInputStream(fis);
System.out.println(dis.readInt());
System.out.println(dis.readLong());
System.out.println(dis.readDouble());
System.out.println(dis.readUTF());
dis.close();
}
}
例子-高级流叠加使用
package day10_19;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
/**
* 高级流的功能可以叠加使用
* 我们既要可以方便的写出基础类型的数据,又要写的效率高
* 那么我们可以联合DOS和BOS一起
*
*/
public class FilterOutputStreamDemo {
public static void main(String[] args) throws Exception{
FileOutputStream fos =
new FileOutputStream("date.dat");
BufferedOutputStream bos =
new BufferedOutputStream(fos);
DataOutputStream dos =
new DataOutputStream(bos);
dos.writeInt(12345);
dos.close();
}
}
字符流
Reader:所有字符输入流的父类
Writer:所有字符输出流的父类
字符流的处理单位为字符,一次处理一个字符,字符流的底层本质上还是使用的读写字节
ISR/OSW
例子-字符输出
package day10_19;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
public class OutputStreamWriteDemo01 {
/**
* 字符输出流
* @throws Exception
*/
public static void main(String[] args) throws Exception {
FileOutputStream fos =
new FileOutputStream("osw.txt");
OutputStreamWriter osw =
new OutputStreamWriter(fos);
/*
* void write(int d)
* 写出一个字符,写出给定int值的"低16位"
*
* void write(char[] c)
* 将给定字符数组中的所有字符一次性全部写出
*
* void write(char[] c,int start,int len)
* 将给定字符数组中从start处开始连续将len个字符写出
*/
/*
* 默认情况下,write()方法会将当前字符串按照系统默认的字符集转换为字节后写出
*/
osw.write("大家好");
osw.close();
}
}
例子-字符输入
package day10_19;
import java.io.FileInputStream;
import java.io.InputStreamReader;
public class InputStreamReaderDemo01 {
/**
* 字符输入流
* @throws Exception
*/
public static void main(String[] args) throws Exception {
FileInputStream fis =
new FileInputStream("osw.txt");
InputStreamReader isr =
new InputStreamReader(fis);
/*
* int read()
* 读取一个字符,并以int值的形式返回
* 该int值"低16位"有效
*
* int read(char[])
* 一次性尝试读取给定字符数组长度的字符,并将读取到的结果存入给定的字符数组中,
* 返回值是实际读取到的字符量
*/
int c = -1;
while((c=isr.read())!=-1) {
System.out.print((char)c);
}
isr.close();
}
}
例子-给定字符集输出
package day10_19;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
public class OutputStreamWriterDemo02 {
/**
* 按照给定的字符集来写出字符
* @throws Exception
*/
public static void main(String[] args) throws Exception {
FileOutputStream fos =
new FileOutputStream("osw2.txt",true);
/*
* OutputStreamWriter(OutputStream out,String )
* 使用给定字符集将字符写出
*/
OutputStreamWriter osw =
new OutputStreamWriter(fos, "UTF-8");
osw.write("大家好");
osw.close();
}
}
例子-给定字符集输入
package day10_19;
import java.io.FileInputStream;
import java.io.InputStreamReader;
public class InputStreamReaderDemo02 {
/**
* 按照指定的字符集读取字符
*/
public static void main(String[] args) throws Exception{
FileInputStream fis =
new FileInputStream("osw2.txt");
InputStreamReader isr =
new InputStreamReader(fis,"UTF-8");
int c = -1;
while((c=isr.read())!=-1){
System.out.println((char)c);
}
isr.close();
}
}
BR/BW
可以按行读取字符串
BufferedReader 缓存字符输入流
BufferedWriter 缓存字符输出流
例子-缓存字符输出
package day10_19;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
public class BufferedWriterDemo {
/**
* 缓存字符输出流
*/
public static void main(String[] args) throws Exception {
FileOutputStream fos =
new FileOutputStream("bw.txt", true);
OutputStreamWriter osw =
new OutputStreamWriter(fos, "UTF-8");
/*
* BufferedWriter(Writer out)
* 将给定的字符输出流转换为缓存字符输出流
*/
BufferedWriter bw =
new BufferedWriter(osw);
bw.write("你好");
bw.close();
}
}
例子-缓存字符输入
package day10_19;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
public class BufferedReaderDemo {
/*
* 缓存字符输入流
*/
public static void main(String[] args) throws Exception{
FileInputStream fis =
new FileInputStream("bw.txt");
InputStreamReader isr=
new InputStreamReader(fis, "UTF-8");
BufferedReader br =
new BufferedReader(isr);
/*
* String readLine()
* 一次读取一行字符串
* 连续读取若干个字符,直到读取到换行符为止
* 返回的字符串中不包含换行符
*/
String str = br.readLine();
System.out.println(str);
//若readLine()读取到null,则说明EOF
str = br.readLine();
System.out.println(str);
br.close();
}
}
PrintWriter
带自动行刷新的缓存字符输出流
构造器
PrintWriter(File file)
PrintWriter(String fileName)
PrintWriter(OutputStream out)
PrintWriter(Writer out)
例子-普通有参构造器
package day10_20;
import java.io.PrintWriter;
public class PrintWriterDemo01 {
public static void main(String[] args) throws Exception {
/*
* PrintWriter(File file)
* PrintWriter(String fileName)
* 写文件时,还可以指定字符集
* PrintWriter(File file,String csn)
* PrintWriter(String fileName,String csn)
*/
PrintWriter pw =
new PrintWriter("pw.txt","UTF-8");
pw.write("大家好");
pw.close();
}
}
例子-自动缓存刷新
package day10_20;
import java.io.FileOutputStream;
import java.io.PrintWriter;
public class PrintWriterDemo02 {
public static void main(String[] args) throws Exception{
/*
* PrintWriter(OutputStream out)
*/
FileOutputStream fos =
new FileOutputStream("pw2.txt");
// PrintWriter pw =
// new PrintWriter(fos);
// pw.write("大家好");
// pw.flush();
/*
* PrintWriter(OutputStream out,boolean autoFlush)
* 创建一个带自动行刷新的缓存字符流
* 如果想要自动调用flush()方法,则需将write()更换成println()方法
*/
PrintWriter pw =
new PrintWriter(fos, true);
pw.println("大家好");
}
}
例子-叠加流
package day10_20;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
public class PrintWriterDemo03 {
public static void main(String[] args) throws Exception{
/*
* PrintWriter(Writer out)
*/
FileOutputStream fos =
new FileOutputStream("pw3.txt", true);
OutputStreamWriter osw =
new OutputStreamWriter(fos, "UTF-8");
PrintWriter pw =
new PrintWriter(osw, true);
pw.println("我爱Java!");
pw.close();
}
}
对象的序列化/反序列化流
ObjectInputStream
对象的反序列化流ObjectOutputStream
对象的序列化流
通常我们序列化对象的目的是用于保存对象和传输对象
例子-序列化与反序列化
首先创建Person类
package day10_20;
public class Person {
//transient关键字:该关键字修饰的属性在序列化时值会被忽略
private String name;
private int age;
private char sex;
public Person() {
}
public Person(String name, int age, char sex) {
super();
this.name = name;
this.age = age;
this.sex = sex;
}
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 char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + sex;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (sex != other.sex)
return false;
return true;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]";
}
}
再创建测试类
package day10_20;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class PersonDemo01 {
public static void main(String[] args) throws Exception{
Person p = new Person("张三",23,'男');
//对象的序列化过程
FileOutputStream fos =
new FileOutputStream("person.obj");//OBJ是对象文件
DataOutputStream dos =
new DataOutputStream(fos);
dos.writeUTF(p.getName());
dos.writeInt(p.getAge());
dos.writeChar(p.getSex());
dos.close();
//对象的反序列化过程
FileInputStream fis =
new FileInputStream("person.obj");
DataInputStream dis =
new DataInputStream(fis);
String name = dis.readUTF();
int age = dis.readInt();
char sex = dis.readChar();
Person p1 = new Person(name,age,sex);
System.out.println(p1);
}
}
测试类2
package day04;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class PersonDemo02 {
public static void main(String[] args) throws Exception{
Person p = new Person("蔡徐坤",25,'男');
//使用OOS序列化对象
FileOutputStream fos =
new FileOutputStream("person2.obj");
ObjectOutputStream oos =
new ObjectOutputStream(fos);
oos.writeObject(p);
oos.close();
//使用OIS反序列化对象
FileInputStream fis =
new FileInputStream("person2.obj");
ObjectInputStream ois =
new ObjectInputStream(fis);
Person person = (Person) ois.readObject();
System.out.println(person);
}
}
最后更新于