IO简介
数据流是一组有序,有起点和终点的字节的数据序列。包括输入流和输出流。
流序列中的数据既可以是未经加工的原始二进制数据,也可以是经一定编码处理后符合某种格式规定的特定数据。因此Java中的流分为两种:
1、字节流:数据流中最小的数据单元是字节
2、 字符流:数据流中最小的数据单元是字符, Java中的字符是Unicode编码,一个字符占用两个字节。
Java.io包中最重要的就是5个类和一个接口。5个类指的是File、OutputStream、InputStream、Writer、Reader;一个接口指的是Serializable。掌握了这些就掌握了Java I/O的精髓了。
IO类结构
1、字节流的学习过程
I/O的架构就是装饰模式(代理模式跟装饰模式的区别www.jianshu.com/p/c06a686da…)
装饰模式 主要是继承 并拓展、增强
以输出流为例:
OutputStream -> FileOutputStream/FilterOutputStream ->DataOutputStream->bufferedOutputStream
字节流实例
1、读写需要一一对应,不然容易出现乱码
2、读写都是对内存的操作
3、输出是指程序往文件传递数据,输入是磁盘文件往程序传入数据。 都是针对程序而言
字节流例子
package com.xm.studyproject.java.io;
import android.util.Log;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 字节流例子 数据流
*/
public class DataStreamTest {
private static final String TAG = "DataStreamTest";
//测试输入流 (就是将内存/磁盘中 读到输入流中 )
void testDataInputStream(File file) {
try {
//FileInputStream extends InputStream
//InputStream 并没有实现read方法 是暴漏出去了
FileInputStream fileInputStream = new FileInputStream(file);
//缓冲流 避免按字节一个个读到内存/磁盘中 DEFAULT_BUFFER_SIZE = 8192
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
//数据的包装类 可以read各种基本类型的数据
DataInputStream dataInputStream = new DataInputStream(bufferedInputStream);
//读的时候需要跟写顺序保持一致 不然会出现错乱
dataInputStream.readBoolean();
dataInputStream.readBoolean();
dataInputStream.readDouble();
//字节地方不推荐使用读行
//dataInputStream.readLine()
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//测试输出流 (就是将流内容输出到磁盘上 )
void testDataOutputStream(File file) {
try {
//同上 OutputStream没有实现write方法
FileOutputStream fileOutputStream = new FileOutputStream(file);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream);
dataOutputStream.writeBoolean(true);
dataOutputStream.write(26);
dataOutputStream.writeChars("测试数据");
dataOutputStream.writeDouble(23.8);
Log.i(TAG, "testDataOutputStream: "+dataOutputStream.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
字节流的 缓冲流实例
package com.xm.studyproject.java.io;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 字节流的 缓冲流实例
* 为了提升Stream的执行效率,所以出现了bufferedOutputStream。bufferedOutputStream就是将本地添加了一个缓存的数组。在使用bufferedOutputStream之前每次从磁盘读入数据的时候都是需要访问多少byte数据就向磁盘中读多少个byte的数据,而出现bufferedOutputSteam之后,策略就改了,会先读取整个缓存空间相应大小的数据,这样就是从磁盘读取了一块比较大的数据,然后缓存起来,从而减少了对磁盘的访问的次数以达到提升性能的目的。
*/
public class BufferStreamTest {
private static final byte[] byteArray = {
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
};
//从流到磁盘中
void testBufferOutStream(File file) {
try {
FileOutputStream fileOutputStream = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream);
bos.write(byteArray[0]);
bos.write(byteArray, 1, byteArray.length - 1);
bos.flush();
bos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
void bufferedInputStream(File file) {
try {
BufferedInputStream bin = new BufferedInputStream(new FileInputStream(file));
for(int i = 0; i < 10; i++) {
//bin.available() 还有数据情况下
if (bin.available() >= 0) {
}
}
//
bin.mark(6666);
bin.skip(10);
byte[] b = new byte[1024];
int n1 = bin.read(b, 0, b.length);
System.out.println("ʣ�����Ч�ֽ��� �� " + n1);
//回到mark位置
bin.reset();
int n2 = bin.read(b,0, b.length);
System.out.println("ʣ�����Ч�ֽ��� �� " + n2);
}catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
## 字符流的学习

字符输入、输出流
package com.xm.studyproject.java.io;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/**
* 字符输入、输出流
*/
public class BufferReaderWriterTest {
void testBufferReader(File file) {
try {
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
//单行字符串值默认是80
//bufferedReader.readLine()
char[] chars = new char[1024];
//一次性读1024个字节 如果内容为空 返回值为-1
while (bufferedReader.read(chars) != -1) {
System.out.println("字符串"+chars.toString());
}
bufferedReader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
void testBufferWriter(File file) {
try {
FileWriter fileWriter = new FileWriter(file);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write("字符串");
bufferedWriter.flush();
bufferedWriter.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
输入流 将字节流转化成字符流
package com.xm.studyproject.java.io;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
/**
* 输入流 将字节流转化成字符流
*/
public class InputStreamReaderTest {
void testInputStreamReader(File file) {
try {
FileInputStream fileInputStream = new FileInputStream(file);
//字符字节转化流 编码格式
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,"UTF-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
char[] chars = new char[1024];
while (bufferedReader.read(chars) != -1) {
System.out.println("字节流转化成字符流" + chars.toString());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
RandomAccessFile
在分段下载中使用
package com.xm.studyproject.java.io;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* RandomAccessFile 注意啊跟InputStream和OutputStream没有任何关系
* 好处:可以指定文件位置读写 所以就是我们可以 分段下载。通过seek( )方法
* 特点1:RandomAccessFile不属于InputStream和OutputStream类系的它是一个完全独立的类,所有方法(绝大多数都只属于它自己)都是自己从头开始规定的,
* 特点2:这里面包含读写两种操作 可设置只读等等模式
*/
public class RandomAccessFileTest {
private static final File file = new File("src\\testtxt\\raf.txt");
void testRandomAccessFile(File file) {
//file有可能是文件也有可能是目录
if (file.exists()) {
file.delete();
}
//参数 mode 的值可选 "r":可读,"w" :可写,"rw":可读性
try {
RandomAccessFile rw = new RandomAccessFile(file, "rw");
//seek(int index);可以将指针移动到某个位置开始读写;
rw.seek(1000);
//setLength(long len);给写入文件预留空间: 这块空间不可操作
rw.setLength(1000);
rw.read(new byte[100]);
rw.writeChar('a');
rw.writeChars("abcde");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}