概念
流是一組有順序的,有起點(diǎn)和終點(diǎn)的字節(jié)集合,是對(duì)數(shù)據(jù)傳輸?shù)目偡Q或抽象。即數(shù)據(jù)在兩設(shè)備間的傳輸稱為流,流的本質(zhì)是數(shù)據(jù)傳輸,根據(jù)數(shù)據(jù)傳輸特性將流抽象為各種類,方便更直觀的進(jìn)行數(shù)據(jù)操作
IO類概述表

常見(jiàn)流
- RandomAccessFile 跳躍讀文件,原理是調(diào)用一個(gè)native方法移動(dòng)指向當(dāng)前操作字節(jié)數(shù)組指針的位置,所以一般對(duì)于流的操作我們就要按照順序讀寫,就可以獲得完整的文件
package com.rockjh.jdk.io;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* @author rockjh 【rockjh@aliyun.com】
* @Description: 隨機(jī)讀寫文件操作demo
* @Date 2017/12/14 15:52
**/
public class RandomAccessFileDemo {
/**
*從這個(gè)類我們可以知道,在底層一直有一個(gè)pos指向當(dāng)前正在讀或者寫的位置,所以一般對(duì)于流的操作我們就要按照順序執(zhí)行
* @param args
* @throws IOException
*/
public static void main(String[] args){
byte[] value= new byte[4];
try {
//獲取resource路徑
String path=RandomAccessFileDemo.class.getResource("/").getPath();
RandomAccessFile randomAccessFile = new RandomAccessFile(path+"RandomAccessFileDemo.txt","r");
//移動(dòng)閱讀的指針,注意漢字在不同編碼里面占的字節(jié)數(shù)不一樣,一般是2-4字節(jié)
randomAccessFile.skipBytes(3);
randomAccessFile.read(value);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(new String(value));
}
}
- 管道流主要是為多個(gè)線程提供通信,一個(gè)輸入管道,一個(gè)輸出管道,一邊輸入一邊輸出
package com.rockjh.jdk.io;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
/**
* @author rockjh 【rockjh@aliyun.com】
* @Description:
* @Date 2017/12/14 16:42
**/
public class PipeStreamDemo {
public static void main(String[] args) throws IOException {
PipedOutputStream pipedOutputStream=new PipedOutputStream();
PipedInputStream pipedInputStream=new PipedInputStream(pipedOutputStream);
Thread thread1=new Thread(() -> {
try {
pipedOutputStream.write("hello world".getBytes("utf-8"));
} catch (IOException e) {
e.printStackTrace();
}
},"thread1");
Thread thread2=new Thread(()->{
try {
byte[] value=new byte[100];
//一直等待讀取狀態(tài)為wait,直到有值
pipedInputStream.read(value);
System.out.println(new String(value));
} catch (IOException e) {
e.printStackTrace();
}
},"thread2");
thread1.start();
thread2.start();
}
}
- FileInputStream文件流
package com.rockjh.jdk.io;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
/**
* @author rockjh 【rockjh@aliyun.com】
* @Description: 文件類demo
* @Date 2017/12/14 21:16
**/
public class FileDemo {
public static void main(String[] args){
try {
File file=new File(FileDemo.class.getResource("/").getPath()+"fileDemo.txt");
if(!file.exists()){
file.createNewFile();
}
OutputStreamWriter output=new FileWriter(file);
char[] value=new char[]{'世','界','你','好'};
output.write(value);
output.flush();
System.out.println(file.isDirectory());
System.out.println(file.list());
} catch (IOException e) {
e.printStackTrace();
}
}
}
ByteArrayOutputStream允許我們以字節(jié)的形式獲取值toByteArray()方法
ObjectOutputStream主要是對(duì)象序列化存儲(chǔ)的一個(gè)東西,他需要一個(gè)將值輸出在構(gòu)造參數(shù)中的流中,相當(dāng)于是一個(gè)包裝流吧
package com.rockjh.jdk.io;
import com.rockjh.jdk.bean.People;
import java.io.*;
/**
* @author rockjh 【rockjh@aliyun.com】
* @Description: 對(duì)象流,序列化對(duì)象
* @Date 2017/12/14 21:30
**/
public class ObjectStreamDemo {
public static void main(String[] args){
//對(duì)象序列化和反序列化
try {
People people=new People("rockjh",23,"18280193473");
ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream(ObjectStreamDemo.class.getResource("").getPath()+"object.data"));
output.writeObject(people);
output.flush();
ObjectInputStream input = new ObjectInputStream(new FileInputStream(ObjectStreamDemo.class.getResource("").getPath()+"object.data"));
people = (People) input.readObject();
System.out.println(people);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
//對(duì)象轉(zhuǎn)byte,byte轉(zhuǎn)對(duì)象
People people=new People("rockjh",23,"18280193473");
System.out.println((People)byteToObj(objToByte(people)));
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 字節(jié)轉(zhuǎn)對(duì)象
* @param bytes
* @param <T>
* @return
* @throws IOException
* @throws ClassNotFoundException
*/
private static <T> T byteToObj(byte[] bytes) throws IOException, ClassNotFoundException {
ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(bytes);
ObjectInputStream inputStream=new ObjectInputStream(byteArrayInputStream);
T t= (T) inputStream.readObject();
return t;
}
/**
* 字節(jié)轉(zhuǎn)對(duì)象
* @param obj
* @param <T>
* @return
* @throws IOException
* @throws ClassNotFoundException
*/
private static <T> byte[] objToByte(T obj) throws IOException {
ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
ObjectOutputStream outputStream=new ObjectOutputStream(byteArrayOutputStream);
outputStream.writeObject(obj);
return byteArrayOutputStream.toByteArray();
}
}
BufferedOutputStream為輸出流提供緩存,能提供很多IO性能,不用每次都去磁盤或者網(wǎng)絡(luò)一次讀取一個(gè)或者幾個(gè)字節(jié)
DataInputStream包裝輸入流,可以使得輸入流直接輸入幾種基本數(shù)據(jù)類型,而不是只能輸入字節(jié)數(shù)據(jù)
System.in, System.out, System.error(注:Java標(biāo)準(zhǔn)輸入、輸出、錯(cuò)誤輸出)
PushBackInputStream可以回退一個(gè)已讀的流
java7新增在try塊中自動(dòng)關(guān)閉流,包括jdbc等
不管輸入流還是輸出流都要有一個(gè)數(shù)據(jù)源,最常見(jiàn)的一個(gè)列子就是實(shí)例化一個(gè)輸入流,向其中寫東西,然后輸出流,輸出到文件或者打印,輸入流是read,輸出流是write
路徑
Object.class.getResource("/").getPath();獲取classpath路徑
Object.class.getResource("").getPath();獲取當(dāng)前類路徑,即包括包
實(shí)例源代碼 前往下載