JAVA–IO流学习笔记
java.io.xx Stream类及代码
流的分类–按流向分类
按流的流动方向来分类可分为:
- 输入流: 外部数据进入内存:称为输入(Input), 或者读(Read)。
- 输出流:从内存中流出,称为输出(Outout),或写(Write)。
流的分类–按读取方式
1.按照字节的方式读取: 一次读一个byte,等同于一次读8个二进制,这种流是万能的,可以读文本文件,图片,声音文件,视频。以读取“a中国” 这段字符为例:
第一次读: “a”
第二次读 : “中”的一半
第三次读 : “中”的另一半
2.按照字符的方式读取:一次读一个字符,这种流是为了方便读取普通文本而存在的。不能读 图片,声音,视频。只能读纯文本文件。仍然以读取“a中国” 这段字符为例:
第一次读: “a”
第二次读 : “中”
第三次读 : “国”
流的分类–按功能分类
Java中读写文件使用java.io包中的类,其中包含文件专属流,转换流,缓冲流,数据流,标准输出流,和对象专属流。
文件专属流
FileInputStream (字节) 以字节的方式将硬盘中的数据,输入内存。
FileOutputStream (字节) 以字节的方式将内存中的数据,输出到硬盘。
FileReader (字符) 以字符的方式将硬盘中的数据,输入内存。
FileWriter (字符) 以字符的方式将内存中的数据,输出到硬盘。
(这里的“硬盘”是泛指,外部设备还有可能是u盘、手机等其他设备)
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class File_input {
public static void main(String[] args) {
FileInputStream f1=null;
try {
f1=new FileInputStream("H:\\TCCS\\re.bib");
// while(readdata!=-1){
// System.out.println(readdata);
// readdata=f1.read();
// }
System.out.println("剩余字节数量"+f1.available()); //批量读取
byte[] bytes=new byte[f1.available()];
int readcount=f1.read(bytes);
System.out.println(new String(bytes,0,readcount));
// byte[] bytes=new byte[100]; //每次读100个字节
// int readcount=0;
// while((readcount=f1.read(bytes))!=-1){
//
// System.out.print(new String(bytes,0,readcount));
//
// }
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(f1!=null){
try {
f1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutput {
public static void main(String[] args) {
FileOutputStream fos=null;
try {
// fos= new FileOutputStream("cesi"); //清空重写
fos= new FileOutputStream("cesi",true); //追加写
byte[] bytes={97,98,99,100};
fos.write(bytes);
fos.write(bytes,0,3);
String s="我爱中国";
byte[] bs=s.getBytes();
fos.write(bs);
fos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos!=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
转换流
负责将一种流转换为另一种,例如字符流>>>>字节流
InputStreamReader
InputStreamWriter
import java.io.*;
public class InputStreamReaderTest {
public static void main(String[] args) {
FileInputStream fin=null;
InputStreamReader isr=null;
FileReader fr=null;
BufferedReader br=null;
try {
fin=new FileInputStream("cesi");
isr=new InputStreamReader(fin);
br=new BufferedReader(isr);
String s=null;
while((s=br.readLine())!=null){
System.out.println(s);
}
br.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
缓冲流
支持逐行读取,自带缓冲区,读文件时无需新建char数组,byte数组等。
BufferedReader (只能处理字符流)
BufferedWriter
BufferedInputStream (只能处理字节流)
BufferedOutputStream
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class BufferedReaderTest {
public static void main(String[] args) {
try {
FileReader fr=new FileReader("cesi");
//此时 FileReader 称为节点流, BufferedReader称为包装流/处理流
BufferedReader br=new BufferedReader(fr); //BufferedReader 只能处理字符流(reader)
String s=null;
while((s=br.readLine())!=null){ //br.readLine()不带换行符
System.out.println(s);
}
br.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
数据流
存/取时需指定数据类型及数据大小方可成功存/取。DataOurputSteam可将数据+数据类型一并写入文件。注意:这个文件不是普通文本文档,用记事本无法打开,只能用DataInputSteam打开,而且打开时也需指定字节,数据类型。所以,这种方式存储文件有点类似加密文件。
DataInputSteam
DataOurputSteam
import java.io.*;
public class DataOutputTest {
public static void main(String[] args) {
DataOutputStream dos=null;
try {
dos=new DataOutputStream(new FileOutputStream("data"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int b=400;
short s=200;
try {
dos.writeShort(s);
dos.writeInt(b);
} catch (IOException e) {
e.printStackTrace();
}
DataInputStream dis=null;
try {
dis=new DataInputStream(new FileInputStream("data"));
try {
System.out.println(dis.read());
System.out.println(dis.readShort());
System.out.println( dis.readInt());
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
标准输出流
PrintWriter
PrintSteam :可改变输出流的方向,比如将System.out的方向转换为log日志文本文件。
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
public class PrintStreamTest {
public static void main(String[] args) {
System.out.println(" hello world!");
PrintStream pst= null;
try {
pst = new PrintStream(new FileOutputStream("log.txt",true)); //true表示追加。
System.setOut(pst); //文本不在向控制台输出,而是输出到log.txt,可用于日志文件。
System.out.println("he;;");
System.out.println("world!");
System.out.println("hello zhangsan");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
对象专属流
用于对象的序列化与反序列化。
ObjectInputSteam 反序列化
ObjectOutputSteam 序列化
- 序列化:Serialize指将java对象切块,编号存入内存的过程。
- 反序列化:DeSerialize将硬盘上的数据恢复到内存当中,恢复成java对象。
- 参与序列化和反序列化的对象所在类,以及类中的属性(基本类型除外),都需实现一个标志性接口Serializable,这个接口中无代码,起到一个标志的作用。此接口可给JVM参考,虚拟机看到此接口,可为该类自动生成一个序列化版本号。
- 若要一次性序列化多个对象,可将多个对象封装成集合,序列化集合。(当然,集合类和对象类也要实现Serializable接口)
// Student---类代码
import java.io.Serializable;
import java.util.Objects;
public class Student implements Comparable<Student>, Serializable { //Comparable<Student> 使其支持哈希表操作需写比较方法; Serializable使其支持序列化操作(这个是虚的,不用写方法)
int no;
String name;
public Student(int no, String name) {
this.no = no;
this.name = name;
}
public Student(int no) {
this.no = no;
}
public Student(){
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return no == student.no;
}
@Override
public int hashCode() {
return Objects.hash(no);
}
@Override
public String toString() {
return "Student{" +
"no=" + no +
", name='" + name + '\'' +
'}';
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int compareTo(Student o) {
return this.no-o.no;
}
}
//序列化代码
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class ObjectOutputStreamTest {
public static void main(String[] args) {
Student s=new Student(11,"白费力");
try {
ObjectOutputStream ops=new ObjectOutputStream(new FileOutputStream("students"));
ops.writeObject(s);
ops.flush();
ops.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//反序列化代码
import java.io.*;
public class ObjectInputStreamTest {
public static void main(String[] args) {
try {
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("students"));
Object obj=ois.readObject();
System.out.println(obj.toString());
ois.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}