Java IO流

Posted 菜菜小谭

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java IO流相关的知识,希望对你有一定的参考价值。

****************************转换流*****************************

作用: 把字节流 转换成 字符流


别人给你一个字节流, 但是我们想以字符为单位读和写,这时需要使用转换流,转换一下

字节 字符


输入 InputStream Reader InputStreamReader


输出 OutputStream Writer OutputStreamWriter


演示代码:


package com.chapter13.演示字节读;

import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;

/**
* 公司:蓝桥软件学院
* 作者:zhangzy
* 时间:2017年7月24日 下午2:02:58
* 功能:演示转换流
*/
public class 演示转换流 {

public static void main(String[] args) throws Exception {

/*FileInputStream fis = new FileInputStream("d:\jidi16\io\HelloIO.txt");//别人给的

Reader reader = new InputStreamReader(fis);


char c = (char)reader.read();
System.out.println(c);*/


FileOutputStream fos = new FileOutputStream("d:\jidi16\io\HelloIO.txt",true);//别人给的 字节流

Writer writer = new OutputStreamWriter(fos);

writer.write(‘好‘);

writer.close();
}
}

 

****************************适配器模式Adapter(转换器)*****************************

描述: 让原本不兼容的接口 变的兼容 达到用户想要的目的

 

package com.degisnPattern.adapter;

//适配器类
//一.实现目标接口(实现想要的)
public class DuckToBirdAdapter implements Bird{

//二.组合现有的
private Duck duck;

public DuckToBirdAdapter(){

}

public DuckToBirdAdapter(Duck duck){
this.duck = duck;
}


@Override
public void fly() {

//三.使用现有的 模拟想要的

for(int i=1;i<=10;i++){
duck.run();
}
}

}


package com.degisnPattern.adapter;

public class Test {

public static void main(String[] args) {

Duck duck = new DonaldDuck();

//Reader new InputStreamReader
Bird bird = new DuckToBirdAdapter(duck);

bird.fly();
}
}

 

*************************************按行读写*****************************

按行读

BufferedReader readLine()


按行写

BufferedWriter write

PrintWriter print 或 println


演示代码:

package com.chapter13.演示字节读;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

/**
* 公司:蓝桥软件学院
* 作者:zhangzy
* 时间:2017年7月24日 下午3:19:20
* 功能:按行读写
*/
public class 演示按行读写 {

public static void main(String[] args) {

String s = "";
//按行读
//一.建立通道
FileReader fr = null;
BufferedReader br = null;
try {
fr = new FileReader("d:\jidi16\io\HelloIO.txt");
br = new BufferedReader(fr);
} catch (FileNotFoundException e) {
System.out.println("文件没有找到");
e.printStackTrace();
System.exit(-1);
}

FileWriter fw = null;;
PrintWriter pw = null;
try {
fw = new FileWriter("d:\jidi16\io\copy.txt");
pw = new PrintWriter(fw);
} catch (IOException e1) {
System.out.println("文件夹没有找到");
e1.printStackTrace();
System.exit(-1);
}


//二.利用read循环读
try {
while((s=br.readLine())!=null){

//ready()是判断有没有下一行
//如果有返回 true 没有返回false
if(br.ready()){

pw.println(s);
}else{
pw.print(s);
}
}
} catch (IOException e) {
System.out.println("文件复制失败");
e.printStackTrace();
}finally{
//三.关闭通道
if(br!=null){
try {
br.close();
} catch (IOException e) {
System.out.println("关闭BufferedReader失败");
e.printStackTrace();
}
}

if(fr!=null){
try {
fr.close();
} catch (IOException e) {
System.out.println("关闭FileReader失败");
e.printStackTrace();
}
}

if(pw!=null){
pw.close();
}

if(fw!=null){
try {
fw.close();
} catch (IOException e) {
System.out.println("关闭FileWriter通道失败");
e.printStackTrace();
}
}

}

}
}


*************************************缓冲流*****************************

 

按行读

BufferedReader readLine()


按行写

BufferedWriter write

PrintWriter print 或 println


以上三个类都是带有缓冲区的, 为什么要使用缓冲流???


因为如果每次读取一个字节, 都要和硬盘打一次交道, 和硬盘打交道开销比较大...效率低


提高存和读的效率

 

硬盘(楼底下 离你500米 垃圾场)


缓冲区(小的垃圾桶)

 


******************************缓冲区中的数据什么时候会真正写到文件中(面试题)*******************************

 

1. 当缓冲流关闭时


close()


调close()方法的时候 底层代码会自动先调用flush()方法


2. 调用缓冲流的flush()时


会把缓冲区的内容写入到硬盘上

 

3. 缓冲区满的时候


会自动把缓冲区的内容写入到文件中

 

缓冲区的实质:字符数组

char[] charArr = new char[8192];

 


***************************************数据流*****************************


字节流 每次读写一个字节

字符流 每次读写一个字符

按行读写 每次以行为单位读写


数据流 每次读写一个数据类型,例如int、long、String等

writeLong()

writeInt()

writeUTF();//写一个字符串 或writeChars(String s)


演示代码:


package com.chapter13.演示数据流;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

/**
* 公司:蓝桥软件学院
* 作者:zhangzy
* 时间:2017年7月24日 下午4:28:56
* 功能:演示数据流
*/
public class 演示数据流 {

public static void main(String[] args) throws Exception {

FileOutputStream fos = new FileOutputStream("d:\jidi16\io\data.txt");

DataOutputStream dos = new DataOutputStream(fos);

dos.writeLong(10);


//数据流 读
FileInputStream fis = new FileInputStream("d:\jidi16\io\data.txt");
DataInputStream dis = new DataInputStream(fis);

long a = dis.readLong();

System.out.println(a);
}
}

 


***************************************对象流*****************************


序列化: 把内存中的对象 保存到文件中 叫做序列化


反序列化: 把文件中的对象 恢复成 内存中的对象 叫做反序列化..

 


知识点:


1. 序列化的对象 所属的类 一定要实现 Serializable 接口,否则运行时会报错,不可序列化的异常


Exception in thread "main" java.io.NotSerializableException: com.chapter12.DVD


//空规范 实现它以后 就可以当它来使用了

public interface Serializable {

}

 

2. transient 关键字 只能用来修饰属性


临时的,使用transient 修饰的属性 不会被 序列化到文件中

 

3. 序列化id


序列化id 唯一的标示一个字节码文件的


序列化时使用的.class文件 反序列化的时候 也要使用同一个.class文件

 

用户没有声明序列化id,IDE会出现一个警告,序列化id是和 类的属性相关的算法 自动产生的..


10


20


Exception in thread "main" java.io.InvalidClassException: com.chapter12.DVD; local class incompatible: stream classdesc serialVersionUID = -7999102326333215443, local class serialVersionUID = 5724934721374926400


演示代码:

package com.chapter13.演示对象流;

import java.io.*;

import java.util.ArrayList;
import java.util.List;

import com.chapter12.DVD;

/**
* 公司:蓝桥软件学院
* 作者:zhangzy
* 时间:2017年7月24日 下午4:51:44
* 功能:演示对象流
*/
public class 演示对象流 {

public static void main(String[] args) throws Exception{

List<DVD> shoppingCart = new ArrayList<DVD>();

DVD dvd1 = new DVD(1,"神偷奶爸3",50);
DVD dvd2 = new DVD(2,"悟空传",60);
DVD dvd3 = new DVD(3,"战狼2",70);

shoppingCart.add(dvd1);
shoppingCart.add(dvd2);
shoppingCart.add(dvd3);

//序列化: 对象 ----->文件中

FileOutputStream fos = new FileOutputStream("d:\jidi16\io\shoppingCart.serial");

ObjectOutputStream oos = new ObjectOutputStream(fos);

oos.writeObject(shoppingCart);


//反序列化: 文件中的对象--------> 内存中的对象


FileInputStream fis = new FileInputStream("d:\jidi16\io\shoppingCart.serial");
ObjectInputStream ois = new ObjectInputStream(fis);

List<DVD> shoppingCart2 = (List<DVD>)ois.readObject();

System.out.println(shoppingCart2);
}
}

*************************************序列化的具体应用*****************************************


RMI= Remote Method Invoke 远程方法调用


RPC= Remote Procedure Call 远程过程调用

 

*************************************装饰者模式 Decorator*****************************************


举例: 披萨店


装饰者模式: 在不改变原有类代码的基础上,给类添加功能(使用组合来实现),可以防止类爆炸


BufferedWriter

DataOutputStream

ObjectOutputStream


这些类都是装饰者类..


*************************************总结*****************************************


字节流、字符流、按行读写、数据流、对象流、转换流

 





































































































































































































































































以上是关于Java IO流的主要内容,如果未能解决你的问题,请参考以下文章

java的io中为啥有那么多种流啊?

Java之IO流总结

java IO流 IO流概述

Java 之IO流及应用

java IO流

Java IO流