Package java.io
- IO 是什么?
官方定义: Provides for system input and output through data streams, serialization and the file system.
简单总结:IO 是提供人机交互的一种方式。
- IO 有哪些种类?
人机操作无非两种操作:读和写。所以,IO 可以分为读流(input)和写流(output)。
注意:
读指:读取系统文件、序列化文件 等类型的数据到数据流中;
写指:将数据流写入磁盘文件。
操作类型可以分为四类:
基于字节操作:inputStream/outputStream
基于字符操作:reader/writer
基于磁盘文件的操作:File
基于网络IO操作:Socket
- 如何使用?
字节流:
BufferedInputStream :
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
public class BufferInputStreamDemo {
/**
* 缓冲输入流,继承FilterInputStream
* 主要作用:
* 1、继承FilterInput,可提供额外一些功能
* 2、为其它字节流提供“缓冲功能”,提高读取效率
* 3、支持reset(),mark()方法,这个两个方式配合使用
* 缓冲步骤:
* 1、bufferedInputStream 从流(磁盘)读取部分字节(bufferSize,可配置)放入缓冲区(内存)
* 2、客户端从缓冲区(内存)读取
* 3、缓冲区数据读取完,bufferedInputStream 再从流中读取部分字节放入缓冲区
* 4、上述步骤反复,知道流中数据读取完毕
* 意义:
* 1、从内存读取数据比从硬盘,效率快10倍左右
* 2、分批读取原因,内存容量小,大批量读取速度慢
*/
public void bufferInputStreamTest() {
byte[] b1 = new byte[]{'1','2','3','4','5','6'};
InputStream is = new ByteArrayInputStream(b1);
BufferedInputStream bis = new BufferedInputStream(is,2);
byte[] b2 = new byte[2];
try {
bis.read(b2);
System.out.println("read():" + new String(b2));
//跳过n个自己
bis.skip(1);
//当前位置标记
bis.mark(1);
//重置当前读取位置
bis.reset();
byte[] b3 = new byte[20];
bis.read(b3, 1, 3);
System.out.println("read()2:" + new String(b3));
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
new BufferInputStreamDemo().bufferInputStreamTest();
}
}
BufferedOutputStream:
import java.io.*;
public class BufferedOutputStreamDemo {
/**
* 缓冲输出流:继承FilterOutputStream ,字节数据输出到文件
* 输出步骤:
* 1、要输出到磁盘(或其它介质)的字节流,首先输出到“缓冲区”(内存)
* 2、判断缓冲区数据量如达到设置字节数,将缓冲区数据写入输出到磁盘
* 3、继续将字节流输出到缓冲区
* 4、依次循环,之到字节流输出完毕
*
* 优点:
* 1、FileOutputStream 每字节需写入磁盘一次;bufferedOutputSteam 先写入缓冲区,达到一定字节写入磁盘一次,效率高
*
*/
public void bufferedOutputStreamTest() {
String path = "G:\\TEST-DELETE.TXT";
File f = new File(path);
try {
long start = System.currentTimeMillis();
OutputStream is = new FileOutputStream(path);
/**
* buffedSize 大小不一样,刷新到文件/硬盘的次数不一样,效率也不一样
*/
BufferedOutputStream bos = new BufferedOutputStream(is, 1000);
for (int i = 0; i < 10000; i++) {
bos.write(i);
// bos.flush();
}
System.out.println(System.currentTimeMillis() - start);
long start2 = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
is.write(i);
// bos.write(i);
// bos.flush();
}
System.out.println(System.currentTimeMillis() - start2);
// Thread.sleep(10);
// FileInputStream readFile = new FileInputStream(path);
// byte[] b2 = new byte[50];
// readFile.read(b2);
//
// System.out.println("read file:" + new String(b2));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new BufferedOutputStreamDemo().bufferedOutputStreamTest();
}
}
DataInputStream:
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
public class DataInputStreamDemo {
/**
* 数据流:继承FilterInputStream,能以一种与机器无关(当前操作系统等)的方式,
* 直接从地从字节输入流读取Java基本类型和String类型的数据,常用于网络传输等(网络传输数据要求与平台无关)
*
*/
public void dateInputStreamTest() {
byte[] bytes=new byte[]{1,3,3,4,5,6,7,8};
InputStream is = new ByteArrayInputStream(bytes);
DataInputStream dis = new DataInputStream(is);
byte[] b1 = new byte[10];
try {
System.out.println("readChar"+dis.readChar());
System.out.println(dis.readShort());
System.out.println("readInt:"+dis.readInt());
System.out.println("readDouble:"+dis.readLong());
System.out.println("" + dis.readBoolean());
System.out.println(dis.readFloat());
System.out.println(dis.readDouble());
System.out.println(dis.readUnsignedByte());
System.out.println(dis.readUnsignedShort());
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
new DataInputStreamDemo().dateInputStreamTest();
}
}
DataOutputStream:
import java.io.*;
public class DataOutputStreamDemo {
public void dataOutputStreamTest() {
try {
OutputStream bos = new FileOutputStream("D:\\test3.txt");
DataOutputStream dos = new DataOutputStream(bos);
dos.writeInt(65);
InputStream is = new FileInputStream("D:\\test3.txt");
byte[] b2 = new byte[10];
is.read(b2);
System.out.println(new String(b2));
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
new DataOutputStreamDemo().dataOutputStreamTest();
}
}
FileInputStream:
import java.io.*;
public class FileInputStreamDemo {
/**
* 1.用于文件读出流,将文件按字节写入byte[]
* 2.线程不安全
* 3.暂不支持reset(重置位置),mark(设置位置)方法
*/
public void fileInputStreamTest() {
File file = new File("D:\\java-test-del\\f1.txt");
try {
InputStream fs = new FileInputStream(file);
int totalLen = (int) file.length();
int off = 1;
byte[] b1 = new byte[totalLen];
/**
* read(b1, off, 10) 方法:从off位置开始,读取10个字节,放到b1字节数组中
*/
fs.read(b1, off, 20);
System.out.println("读取文件到byte[]:" + new String(b1));
/**
* skip()方法:跳过n个字节,当前位置为off+n,读取时从当前文件开始
*/
fs.skip(20);
byte[] b2 = new byte[totalLen];
fs.read(b2, off, 20);
System.out.println("skip移位后,读取文件到byte[]:" + new String(b2));
//fs.reset(); //不支持reset 和 mark 方法
byte[] b3 = new byte[totalLen];
fs.read(b3);
System.out.println("skip移位后,读取文件到byte[]:" + new String(b3));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new FileInputStreamDemo().fileInputStreamTest();
}
}
FileOutputStream:
import java.io.*;
public class FileOutputStreamDemo {
public void fileOutputStreamTest() {
String path = "D:\\java-test-del\\f2.txt";
File file = new File(path);
try {
if (!file.exists()) {
file.createNewFile();
}
FileOutputStream ops = new FileOutputStream(file);
byte[] b1 = {'a', 'b', 'c'};
ops.write(b1);
System.out.println("b1字节数组写入文件:"+readFile(path));
byte[] b2 = {'e', 'f', 'g'};
ops.write(b2, 1, 2);
System.out.println("b2字节数组写入文件:"+readFile(path));
ops.write(22);
System.out.println("int 类型值写入文件:" + readFile(path));
ops.getChannel();//todo ?
ops.getFD();//todo ?
} catch (IOException e) {
e.printStackTrace();
}
}
public String readFile(String path) {
File file = new File(path);
try {
InputStream is = new FileInputStream(file);
byte[] b1 = new byte[(int)file.length()];
is.read(b1);
return new String(b1);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args){
new FileOutputStreamDemo().fileOutputStreamTest();
}
}
FilterInputStream:
import java.io.ByteArrayInputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
public class FilterInputStreamDemo extends FilterInputStream{
/**
* 1、继承inputString,各方法实现用inputStream原生方法实现
* 2、主要意义在于类似装饰者模式,继承公共父类提供标准使用并扩展一些功能,继承filterInputStream子类可重写FilterInputStream方法,再向下层提供服务
* 3、
*/
/**
* Creates a <code>FilterInputStream</code>
* by assigning the argument <code>in</code>
* to the field <code>this.in</code> so as
* to remember it for later use.
*
* @param in the underlying input stream, or <code>null</code> if
* this instance is to be created without an underlying stream.
*/
protected FilterInputStreamDemo(InputStream in) {
super(in);
}
@Override
public int read() throws IOException {
System.out.println("自定义实现read方法...");
return super.read();
}
public static void main(String[] args){
byte[] bytes = {'a', 'b', 2, 3, 4, 5, 6};
InputStream bis = new ByteArrayInputStream(bytes);
FilterInputStreamDemo fis = new FilterInputStreamDemo(bis);
try {
fis.read();
fis.read(bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
}
FilterOutputStrea:
import java.io.FilterOutputStream;
import java.io.OutputStream;
public class FilterOutputStreamDemo extends FilterOutputStream {
/**
* Creates an output stream filter built on top of the specified
* underlying output stream.
*
* @param out the underlying output stream to be assigned to
* the field <tt>this.out</tt> for later use, or
* <code>null</code> if this instance is to be
* created without an underlying stream.
*/
public FilterOutputStreamDemo(OutputStream out) {
super(out);
}
/**
* 类似与FilterInputStreamDemo使用方式
*/
}
SequenceInputStream:
import java.io.*;
import java.util.Vector;
public class SequenceInputStreamDemo {
/**
* 合并流:将多个流合并成一个sequenceInputStream对象。
* 读取:从一个流开始,读到流末位;开始读取第二个流到末尾,依次类推读最后一个流。
*/
public void sequenceInputStreamTest() {
InputStream is1 =new ByteArrayInputStream(new byte[]{'1', '2', '3', '4', '5', '6', '7'});
InputStream is2 = new ByteArrayInputStream(new byte[]{'a', 'b', 'c', 'd', 'e', 'f'});
InputStream is3 = new ByteArrayInputStream(new byte[]{'g', 'h', 'C', 'D', 'E', 'F', 'G'});
InputStream is4 = new BufferedInputStream(is3);
Vector vector = new Vector();
vector.add(is4);
try (SequenceInputStream sis2 = new SequenceInputStream(vector.elements()); SequenceInputStream sis = new SequenceInputStream(is1, is2)) {
byte[] resBy = new byte[10];
do {
sis.read(resBy);
System.out.println("read():" + new String(resBy));
} while (sis.read() != -1);
byte[] resBy2 = new byte[100];
do {
sis2.read(resBy2);
System.out.println("read()3:" + new String(resBy2));
} while (sis2.read() != -1);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new SequenceInputStreamDemo().sequenceInputStreamTest();
}
}
字符流:
BufferedWriter 与 BufferedReader:
import java.io.*;
public class BufferedReaderDemo {
/**
* 介质---->内存
* BufferedWriter 继承 Writer
* 主要作用:将基本“字符输出流”使用“缓冲输出字符流”输出
* 实现过程:
* 1、将基本字符流写入“缓冲区”(内存),可以设置写入大小,默认 8192 byte
* 2、当前缓冲区大小>=设置缓冲区大小,将缓冲区数据刷入基本字符流
*/
public void bufferedWriterTest() {
String str = "hello world";
StringWriter stringWriter = new StringWriter();
BufferedWriter bufferedWriter = new BufferedWriter(stringWriter);
try {
bufferedWriter.write(str);
bufferedWriter.flush();
StringBuffer stringBuffer = stringWriter.getBuffer();
System.out.println("getBuffer:"+stringBuffer);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 内存---->存储介质
* BufferedReader 继承 Reader
* 主要作用:将存内存中的数据,通过bufferReader作为中间介质读取到指定字符流
* 实现过程:
* 1、先内存中读取指定字节数据,字节数可设置,默认为 8192 byte
* 2、用户读取先从缓冲区读取
* 3、缓冲区数据读取完,再批量写入指定大小字节数据到缓冲区
* 4、一次重复,直到流中数据读取完毕
*/
public void bufferedReaderTest() {
char[] chars = new char[]{'1','2','3','4','5','6'};
CharArrayReader charArrayReader = new CharArrayReader(chars);
BufferedReader reader = new BufferedReader(charArrayReader);
char[] readChars = new char[20];
try {
reader.read(readChars);
System.out.println("read():"+new String(readChars));
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
new BufferedReaderDemo().bufferedWriterTest();
new BufferedReaderDemo().bufferedReaderTest();
}
}
CharArrayWriter 和 CharArrayReader:
import java.io.CharArrayReader;
import java.io.CharArrayWriter;
import java.io.IOException;
public class CharArrayWRdemo {
public void charArrayWriterTest() {
CharArrayWriter writer = new CharArrayWriter();
char[] chars = new char[]{'1', '2', '3', '4', '5'};
try {
System.out.println("---------------charArrayWriter---------------");
writer.write(chars);
writer.flush();
//
System.out.println("toCharArray:"+new String(writer.toCharArray()));
System.out.println("toString:" + new String(writer.toString()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void charArrayReaderTest() {
char[] chars = new char[]{'1','2','3','4','5','6','7','8'};
CharArrayReader reader = new CharArrayReader(chars);
char[] charRead = new char[20];
try {
System.out.println("---------------charArrayReader---------------");
reader.read(charRead, 0, 2);
System.out.println("read(,,,):" + new String(charRead));
reader.skip(2);
reader.read(charRead, 0, 2);
System.out.println("read(,,,):" + new String(charRead));
reader.mark(1);//源码骗我读书少
reader.reset();//源码骗我读书少
reader.read(charRead, 0, 2);
System.out.println("read(,,,):" + new String(charRead));
reader.read(charRead);
System.out.println("read():" + new String(charRead));
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
new CharArrayWRdemo().charArrayWriterTest();
new CharArrayWRdemo().charArrayReaderTest();
}
}
OutputStreamWriter 和 OutputStreamReader:
import sun.nio.cs.ext.GBK;
import java.io.*;
public class InputStreamRWdemo {
String path = "D:\\java-test-del\\f2.txt";
/**
* outStreamWriter 继承writer接口
* 主要作用:将“字节输出流”转换成“字符输出流”
*/
public void outPutStreamWriterTest() {
try {
OutputStream outputStream = new FileOutputStream(path);
OutputStreamWriter writer = new OutputStreamWriter(outputStream, new GBK());
String str = "outStreamWriterTest";
writer.write(str);
writer.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* inputStreamReader 继承Reader接口
* 主要作用:将“字节输入流”转换成“字符输入流”
*/
public void inputStreamReaderTest() {
try {
InputStream inputStream = new FileInputStream(path);
InputStreamReader reader = new InputStreamReader(inputStream, new GBK());
char[] chars = new char[100];
System.out.println("encoding:"+reader.getEncoding());
reader.read(chars);
System.out.println("read():" + new String(chars));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
new InputStreamRWdemo().outPutStreamWriterTest();
new InputStreamRWdemo().inputStreamReaderTest();
}
}
PipedWriter 和 PipedReader:
import java.io.IOException;
import java.io.PipedReader;
import java.io.PipedWriter;
public class PipedRWdemo {
/**
* PipedWtriter 和 PipedReader 用户两个线程间共享数据,
* 详细介绍请阅读PipeIOstreamDemo例子的详细介绍
*/
static class WriterC implements Runnable {
PipedWriter pipedWriter = new PipedWriter();
public PipedWriter getPipedWriter() {
return pipedWriter;
}
@Override
public void run() {
char[] chars = new char[]{'1', '2', '3', '4', '5'};
try {
System.out.println("---------------线程"+Thread.currentThread().getName()+"写入数据----------------");
pipedWriter.write(chars);
} catch (IOException e) {
e.printStackTrace();
}
}
}
static class ReaderC implements Runnable {
PipedReader pipedReader = new PipedReader();
PipedReader getPipedReader() {
return this.pipedReader;
}
@Override
public void run() {
char[] chars = new char[20];
try {
System.out.println("---------------线程"+Thread.currentThread().getName()+"写入数据----------------");
pipedReader.read(chars);
System.out.println("线程"+Thread.currentThread().getName()+"读取数据为:"+new String(chars));
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args){
WriterC writerC = new WriterC();
ReaderC readerC = new ReaderC();
PipedWriter pipedWriter = writerC.getPipedWriter();
PipedReader pipedReader = readerC.getPipedReader();
try {
pipedReader.connect(pipedWriter);
writerC.run();
readerC.run();
} catch (IOException e) {
e.printStackTrace();
}
}
}
StringReader 和 StringWriter:
import java.io.IOException;
import java.io.StringReader;
public class StringRWdemo {
/**
* 1、char 是java保留字,1btye=8bit 1char=2byte,兼容跨平台,用Unicode表示。
* 2、操作char
* 3、线程安全,实现同步
*/
public void StringReaderTest() {
String str = "ABCDEFGHI";
try {
StringReader sr = new StringReader(str);
System.out.println("read()" + sr.read());
char[] chars = new char[10];
sr.read(chars, 2,4);
System.out.println("read(chars, 2, 5):" +new String(chars));
/** 校验字符串是否为空:读取字符串不为Null返回true,否则返回false **/
String s=" 2";
StringReader sr2=new StringReader(s);
System.out.println("ready():"+sr2.ready());
char[] chars2 = new char[10];
/** **/
sr.read(chars2);
System.out.println("reade(char []):" + new String(chars2));
char[] chars3 = new char[10];
sr.mark(1);//感觉没有实际用途
sr.reset();
sr.read(chars3);
System.out.println("reade(char []):" + new String(chars3));
} catch (IOException e) {
e.printStackTrace();
}
}
public void stringWriterTest() {
StringWriter sw = new StringWriter();
//写入单个char ASCII 值表示
sw.write(66);
System.out.println(sw);
char[] chars = {65,66,67,68,69,70};
sw.write(chars, 1, 5);
System.out.println("write(chars, 1, 2):" + sw);
sw.write("Z");
System.out.println("write(Stirng):" + sw);
String str = "HIGKLMN";
sw.write(str, 0, 3);
System.out.println("write(String,off,len):" + sw);
sw.append("99");
System.out.println("append(char):" + sw);
System.out.println("getBuffer:"+sw.getBuffer());
}
public static void main(String[] args){
new StringRWdemo().StringReaderTest();
}
}
- 读取磁盘文件流程简图: