java IO流
内存与存储设备之间传输数据的通道
流的分类
按方向分:
-
输入流:将<存储设备>中的内容读入到<内存>中
-
输出流:将<内存中的内容写入到<存储设备>中
按单位分:
-
字节流:以字节为单位,可以读写所有数据
-
按功能分:
-
节点流:具有实际传输数据的读写功能
-
过滤流:在节点流的基础上增强功能
字节流
字节流的父类(抽象类)
-
InputStream:字节输入流
-
public int read(){}
-
public int read(byte[] b){}
-
public int read(byte[] b, int off, int len){}
-
-
OutputSream:字节输出流
-
public void write(int n){}
-
public void write(byte[] b){}
-
public void write(byte[] b, int off, int len){}
-
文件字节流
-
FileInputStream:
-
public int read(byte[] b) //从流中读取多个字节,将读到内容存入b数组,返回实际读到的字节数;如果到达文件尾部,则返回-1
public class Demo1 {
public static void main(String[] args) throws Exception{
//1 创建FileInputStream,并指定文件路径
FileInputStream fis = new FileInputStream("d:\\aaa.txt");
//2 读取文件
//2.1 单个字节读取
int data = 0;
while((data = fis.read())!=-1){
System.out.println((char)data);
}
//2.2 多个字节读取
byte[] buf = new byte[1024];
int count = 0;
while ((count = fis.read(buf))!=-1){
System.out.println(new String(buf,0,count));
}
//3 关闭
fis.close();
}
} -
-
FileOutputSream:
-
public void write(byte[] b) //一次写入多个字节,将b数组中所有字节,写入输出流
public class Demo1 {
public static void main(String[] args) throws Exception {
//1 创建FileOutputStream,并指定文件路径
FileOutputStream fos = new FileOutputStream("d:\\aaa.txt",true);
//true则表示文件可以继续写而不会被覆盖,默认为false
//2 写入文件
fos.write(97);
fos.write('b');
fos.write('c');
String string = "helloworld";
fos.write(string.getBytes());
//3 关闭
fos.close();
}
} -
文件复制(案例)
public class Demo1 {
public static void main(String[] args) throws Exception {
FileInputStream fis = new FileInputStream("d:\\001.jpg");
FileOutputStream fos = new FileOutputStream("d:\\002.jpg");
byte[] buf = new byte[1024];
int count = 0;
while ((count=fis.read(buf))!=-1){
fos.write(buf,0,count);
}
fos.close();
fis.close();
}
}
字节缓冲流
-
缓冲流:BufferedInputStream/BufferedOutputStream
-
提高IO效率,减少磁盘访问次数
-
数据存储在缓存区中,flush是将缓存区的内容写入文件中,也可以直接close
-
-
读文件
public class Demo1 {
public static void main(String[] args) throws Exception{
FileInputStream fis = new FileInputStream("d:\\aaa.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
int data = 0;
while ((data= bis.read())!=-1){
System.out.println((char)data);
}
//也可以自己创建一个缓存区
byte[] buf = new byte[1024];
int count = 0;
while ((count = bis.read(buf))!=-1){
System.out.println(new String(buf,0,count));
}
bis.close();
}
}
-
写文件
public class Demo1 {
public static void main(String[] args) throws Exception{
FileOutputStream fos = new FileOutputStream("d:\\buffer.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
for (int i = 0; i < 10; i++) {
bos.write("helloworld".getBytes());//写入8K缓存区
bos.flush();//刷新到硬盘
}
//close内部会调用flush方法
bos.close();
}
}
对象流
对象流:ObjectInputStream/ObjectOutputStream
-
增强了缓冲区功能
-
增强了读写8种基本数据类型和字符串功能
-
增强了读写对象的功能
-
readObject() 从流中读取一个对象(反序列化)
-
writeObject(Object obj) 向流中写入一个对象(序列化)
-
学生类
public class student implements Serializable {//实现Serializable接口
private String name;
private int age;
public student(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
序列化
/**
* 要求:序列化的类必须要实现Serializable接口
*/
public class Demo1 {
public static void main(String[] args) throws Exception{
//1 创建对象流
FileOutputStream fos = new FileOutputStream("d:\\stu.bin");
ObjectOutputStream oos = new ObjectOutputStream(fos);
//2 序列化(写入操作)
student zhangsan = new student("张三",20);
oos.writeObject(zhangsan);
//3 关闭
oos.close();
}
}
反序列化
public class Demo1 {
public static void main(String[] args) throws Exception {
//创建对象流
FileInputStream fis = new FileInputStream("d:\\stu.bin");
ObjectInputStream ois = new ObjectInputStream(fis);
//读取文件
student s = (student) ois.readObject();
//关闭
ois.close();
System.out.println(s.toString());
}
}
序列化和反序列化注意事项
-
序列化的类必须要实现Serializable接口
-
序列化的类中的对象属性也要求实现Serializable接口
-
serialVersionUID:序列化版本号ID,保证序列化的类和反序列化的类是同一个类
private static final long serialVersionUID = 100L;//这个数值是可以自定义的
-
使用transient(瞬间的)修饰属性,这个属性就不能被序列化
-
静态属性不能序列化
-
序列化多个对象时,可以借助集合实现
public class Demo1 {
public static void main(String[] args) throws Exception {
//1 创建对象流
FileOutputStream fos = new FileOutputStream("d:\\stu.bin");
ObjectOutputStream oos = new ObjectOutputStream(fos);
//2 序列化(写入操作)
student zhangsan = new student("张三", 20);
student lisi = new student("李四", 22);
// oos.writeObject(zhangsan);
// oos.writeObject(lisi);
ArrayList<student> list = new ArrayList<>();
list.add(zhangsan);
list.add(lisi);
oos.writeObject(list);
oos.close();
}
}
public class Demo2 {
public static void main(String[] args) throws Exception{
FileInputStream fis = new FileInputStream("d:\\stu.bin");
ObjectInputStream ois = new ObjectInputStream(fis);
//读取文件
ArrayList<student> list = (ArrayList<student>) ois.readObject();
//关闭
ois.close();
System.out.println(list.toString());
}
}
字符流
常见的字符编码
编码方式和解码方式不一样时会出现乱码
-
ISO-8859-1 包括ASCII 西欧 希腊语 泰语 阿拉伯语 希伯来语对应的文字符号(一个字节,只能表示255个字符)
-
UTF-8 万国码(1/2/3个字节表示)
-
GB2312 简体中文(1/2个字节表示)
-
GBK 简体中文,扩充(1/2个字节表示)
-
BIG5 台湾,繁体中文
字符流的父类(抽象类)
-
Reader:字符输入流
-
public int read(){}
-
public int read(char[] c){}
-
public int read(char[] c, int off, int len){}
-
-
Writer:字符输出流
-
public void write(int n){}
-
public void write(String str){}
-
public void write(char[] c){}
-
文件字符流
-
FileReader:
-
public int read(char[] c) //从流中读取多个字符,将读到内容存入c数组,返回实际读到的字符数;如果到达文件尾部,则返回-1
-
public class Demo1 {
public static void main(String[] args) throws Exception {
FileReader fr = new FileReader("d:\\hello.txt");
//单个字符读取
int data=0;
while ((data=fr.read())!=-1){
System.out.print((char) data);
}
//自建缓存区,一次性读取
char[] buf = new char[1024];
int count = 0;
while ((count= fr.read(buf))!=-1){
System.out.println(new String(buf,0,count));
}
fr.close();
}
}
-
FileWriter:
-
public void write(String str) //一次写入多个字符
-
public class Demo1 {
public static void main(String[] args) throws Exception {
FileWriter fw = new FileWriter("d:\\hello.txt");
//单个字符读取
for (int i = 0; i < 10; i++) {
fw.write("Java是世界上最好的语言\r\n");
fw.flush();
}
fw.close();
}
}
使用FileReader和FileWriter只能复制文本文件,不能复制图片或者二进制文件
因为图片和二进制文件没有字符编码
字符缓冲流
-
缓冲流:BufferedReader/BufferedWriter
-
优点
-
高效读写
-
支持输入换行符
-
可一次写一行,读一行
-
-
BufferedReader
public class Demo1 {
public static void main(String[] args) throws Exception {
FileReader fr = new FileReader("d:\\write.txt");
BufferedReader br = new BufferedReader(fr);
//一行一行读
String line = null;
while ((line = br.readLine())!=null){
System.out.println((line);
}
//可以自己创建一个缓存区
char[] buf = new char[1024];
int count = 0;
while ((count = br.read(buf))!=-1){
System.out.println(new String(buf,0,count));
}
br.close();
}
}
-
BufferedWriter
public class Demo1 {
public static void main(String[] args) throws Exception {
FileWriter fw = new FileWriter("d:\\write.txt");
BufferedWriter bw = new BufferedWriter(fw);
for (int i = 0; i < 10; i++) {
bw.write("好好学习,天天向上");
bw.newLine();//写入一个换行符(每个系统的换行符不一样,但这个方法均适配)
bw.flush();
}
bw.close();
}
}
打印流
-
PrintWriter:
-
封装了print()/println()方法,支持写入后换行
-
支持数据原样打印
-
public class Demo1 {
public static void main(String[] args) throws Exception {
PrintWriter pw = new PrintWriter("d:\\print.txt");
pw.println(97);
pw.println(true);
pw.println(3.14);
pw.println('a');
pw.close();
}
}
转换流
-
桥转换流:InputStreamReader/OutputStreamWriter
-
可将字节流转换为字符流
-
可设置字符的编码方式
-
-
InputStreamReader
public class Demo1 {
public static void main(String[] args) throws Exception {
FileInputStream fis = new FileInputStream("d:\\writer.txt");
InputStreamReader irs = new InputStreamReader(fis,"utf-8");
int data = 0;
while ((data = irs.read())!=-1){
System.out.print((char)data);
}
irs.close();
}
}
-
OutputStreamWriter
public class Demo1 {
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("d:\\info.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos,"gbk");
for (int i = 0; i < 10; i++) {
osw.write("我爱川农\r\n");
osw.flush();
}
osw.close();
}
}
浙公网安备 33010602011771号