字节数组流ByteArrayInputStream和ByteArrayOutputStream
经常用在需要流和数组之间转化
FileInputStream是把文件当做数据源。ByteArrayInputStream则是把内存中的”某个字节数组对象”当做数据源。
import java.io.ByteArrayInputStream;
import java.io.IOException;
public class TestByteArray {
public static void main(String[] args) {
//将字符串转变成字节数组
byte[] b = "abcdefg".getBytes();
test(b);
}
public static void test(byte[] b) {
ByteArrayInputStream bais = null;
StringBuilder sb = new StringBuilder();
int temp = 0;
//用于保存读取的字节数
int num = 0;
try {
//该构造方法的参数是一个字节数组,这个字节数组就是数据源
bais = new ByteArrayInputStream(b);
while ((temp = bais.read()) != -1) {
sb.append((char) temp);
num++;
}
System.out.println(sb);
System.out.println("读取的字节数:" + num);
} finally {
try {
if (bais != null) {
bais.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
数据流DataInputStream和DataOutputStream
数据流将“基本数据类型与字符串类型”作为数据源,从而允许程序以与机器无关的方式从底层输入输出流中操作Java基本数据类型与字符串类型。
public class TestDataStream {
public static void main(String[] args) {
DataOutputStream dos = null;
DataInputStream dis = null;
FileOutputStream fos = null;
FileInputStream fis = null;
try {
fos = new FileOutputStream("D:/data.txt");
fis = new FileInputStream("D:/data.txt");
//使用数据流对缓冲流进行包装,新增缓冲功能
dos = new DataOutputStream(new BufferedOutputStream(fos));
dis = new DataInputStream(new BufferedInputStream(fis));
//将如下数据写入到文件中
dos.writeChar('a');
dos.writeInt(10);
dos.writeDouble(Math.random());
dos.writeBoolean(true);
dos.writeUTF("北京尚学堂");
//手动刷新缓冲区:将流中数据写入到文件中
dos.flush();
//直接读取数据:读取的顺序要与写入的顺序一致,否则不能正确读取数据。
System.out.println("char: " + dis.readChar());
System.out.println("int: " + dis.readInt());
System.out.println("double: " + dis.readDouble());
System.out.println("boolean: " + dis.readBoolean());
System.out.println("String: " + dis.readUTF());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(dos!=null){
dos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(dis!=null){
dis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(fos!=null){
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(fis!=null){
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
对象流
如果要对某个对象进行读写操作,我们需要学习一对新的处理流:ObjectInputStream/ObjectOutputStream。
ObjectInputStream/ObjectOutputStream是以“对象”为数据源,但是必须将传输的对象进行序列化与反序列化操作。
注:序列化实体类实现序列化接口时
serialVersionUID适用于Java的序列化机制。简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常,即是InvalidCastException。
public class TestObjectStream {
public static void main(String[] args) throws IOException, ClassNotFoundException {
write();
read();
}
/**使用对象输出流将数据写入文件*/
public static void write(){
// 创建Object输出流,并包装缓冲流,增加缓冲功能
OutputStream os = null;
BufferedOutputStream bos = null;
ObjectOutputStream oos = null;
try {
os = new FileOutputStream(new File("d:/bjsxt.txt"));
bos = new BufferedOutputStream(os);
oos = new ObjectOutputStream(bos);
// 使用Object输出流
//对象流也可以对基本数据类型进行读写操作
oos.writeInt(12);
oos.writeDouble(3.14);
oos.writeChar('A');
oos.writeBoolean(true);
//对象流能够对对象数据类型进行读写操作
//Date是系统提供的类,已经实现了序列化接口
//如果是自定义类,则需要自己实现序列化接口
oos.writeObject(new Date());
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭输出流
if(oos != null){
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bos != null){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(os != null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**使用对象输入流将数据读入程序*/
public static void read() {
// 创建Object输入流
InputStream is = null;
BufferedInputStream bis = null;
ObjectInputStream ois = null;
try {
is = new FileInputStream(new File("d:/bjsxt.txt"));
bis = new BufferedInputStream(is);
ois = new ObjectInputStream(bis);
// 使用Object输入流按照写入顺序读取
System.out.println(ois.readInt());
System.out.println(ois.readDouble());
System.out.println(ois.readChar());
System.out.println(ois.readBoolean());
System.out.println(ois.readObject().toString());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭Object输入流
if(ois != null){
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bis != null){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
转换流
InputStreamReader/OutputStreamWriter用来实现将字节流转化成字符流。
System.in是字节流对象,代表键盘的输入,如果我们想按行接收用户的输入时,就必须用到缓冲字符流BufferedReader特有的方法readLine(),但是经过观察会发现在创建BufferedReader的构造方法的参数必须是一个Reader对象,这时候我们的转换流。
而System.out也是字节流对象,代表输出到显示器,按行读取用户的输入后,并且要将读取的一行字符串直接显示到控制台,就需要用到字符流的write(String str)方法,所以我们要使用OutputStreamWriter将字节流转化为字符流。
使用InputStreamReader接收用户的输入,并输出到控制台
public class TestConvertStream {
public static void main(String[] args) {
// 创建字符输入和输出流:使用转换流将字节流转换成字符流
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new InputStreamReader(System.in));
bw = new BufferedWriter(new OutputStreamWriter(System.out));
// 使用字符输入和输出流
String str = br.readLine();
// 一直读取,直到用户输入了exit为止
while (!"exit".equals(str)) {
// 写到控制台
bw.write(str);
bw.newLine();// 写一行后换行
bw.flush();// 手动刷新
// 再读一行
str = br.readLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭字符输入和输出流
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bw != null) {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
©著作权归作者所有:来自51CTO博客作者huingsn的原创作品,如需转载,请注明出处,否则将追究法律责任