Java-IO处理流

目录

 

处理流

缓冲流(Buffering)

缓冲流测试:BufferedInputStream

缓冲流测试:BufferedReader

转换流

转换流测试代码

数据流

数据流测试代码

打印流(Print)

对象流(Object)


处理流

缓冲流(Buffering)

缓冲流要”套接“在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法

常用构造方法如下:

BufferedReader(Reader in)
BufferedReader(Reader in,int sz) //sz 为自定义缓冲区的大小
BufferedWriter(Writer out)
BufferedWriter(Writer out,int sz)
BufferedInputStream(InputStream in)
BufferedInputStream(InputStream in,int size)
BufferedOutputStream(InputStream in)
BufferedOutputStream(InputStream in,int size)
  • 缓冲输入流支持其父类的mark和reset方法。
  • BufferedReader提供了readLine方法用于读取一行字符串
  • BufferedWriter提供了newLine用于写入一个行分隔符
  • 对于输出的缓冲流,写出的数据会现在内存中缓存,使用flush方法将会使内存中的数据立刻写出

缓冲流测试:BufferedInputStream

package com.kou.chapter;
import java.io.*;
public class TestBufferStream {
public static void main(String args[]) {
FileInputStream fis = null;
try {
fis = new FileInputStream("D:\\IDEA\\CODE\\JAVASE\\src\\com\\kou\\chapter\\student.java");
// 在FileInputStream节点流的外面套接一层处理流BufferedInputStream
BufferedInputStream bis = new BufferedInputStream(fis);
int c = 0;
System.out.println((char) bis.read());
System.out.println((char) bis.read());
bis.mark(100);// 在第100个字符处做一个标记
for (int i = 0; i <= 10 && (c = bis.read()) != -1; i++) {
System.out.print((char) c);
}
System.out.println();
bis.reset();// 重新回到原来标记的地方
for (int i = 0; i <= 10 && (c = bis.read()) != -1; i++) {
System.out.print((char) c);
}
bis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e1) {
e1.printStackTrace();
}
}
}

缓冲流测试:BufferedReader

package com.kou.chapter;
import java.io.*;
public class TestBufferStream{
public static void main(String args[]){
try{
BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\IDEA\\CODE\\JAVASE\\src\\com\\kou\\chapter\\student.txt"));
//在节点流FileWriter的外面再套一层处理流BufferedWriter
String s = null;
for(int i=0;i<100;i++){
s = String.valueOf(Math.random());//“Math.random()”将会生成一
系列介于0~1之间的随机数。
// static String valueOf(double d)这个valueOf()方法的作用就是把
一个double类型的数转换成字符串
//valueOf()是一个静态方法,所以可以使用“类型.静态方法名”的形式来调用
bw.write(s);//把随机数字符串写入到指定文件中
bw.newLine();//调用newLine()方法使得每写入一个随机数就换行显示
}
bw.flush();//调用flush()方法清空缓冲区
BufferedReader br = new BufferedReader(new FileReader("D:\\IDEA\\CODE\\JAVASE\\src\\com\\kou\\chapter\\student.txt"));
//在节点流FileReader的外面再套一层处理流BufferedReader
while((s = br.readLine())!=null){
//使用BufferedReader处理流里面提供String readLine()方法读取文件中
的数据时是一行一行读取的
//循环结束的条件就是使用readLine()方法读取数据返回的字符串为空值后则表
示已经读取到文件的末尾了。
System.out.println(s);
}
bw.close();
br.close();
}catch(Exception e){
e.printStackTrace();
}
}
}

程序的输入指的是把从文件读取到的内容存储到为程序分配的内存区域里面去。流,什么是流,流无非就是两根管道,一根向里,一根向外,向里向外都是对于我们自己写的程序来说,流分为各种各样的类型,不同的分类方式又可以分为不同的类型,根据方向来分,分为输入流和输出流,根据读取数据的单位的不同,又可以分为字符流和字节流,除此之外,还可以分为节点流和处理流,节点流就是直接和数据源连接的流,处理流就是包在其它流上面的流,处理流不是直接和数据源连接,而是从数据源读取到数据以后再通过处理流处理一遍。缓冲流也包含了四个类:

BufferedInputStream、BufferedOutputStream、BufferedReader和BufferedWriter。

流都是成对的,没有流是是不成对的,肯定是一个in,一个out。

转换流

  • InputStreamReader 和 OutputStreamWriter 用于字节数据到字符数据之间的转换
  • InputStreamReader 需要和 InputStream “套接” 。
  • OutputStreamWriter 需要和 OutputStream “套接” 。
  • 转换流在构造时可以指定其编码集合
InputStream isr = new InputStreamReader(System.in,"ISO8859-1")

转换流非常的有用,它可以把一个字节流转换成一个字符流

转换流有两种,一种叫InputStreamReader,另一种叫OutputStreamWriter。InputStream是字节流,Reader是字符流,InputStreamReader就是把InputStream转换成Reader。

OutputStream是字节流,Writer是字符流,OutputStreamWriter就是把OutputStream转换成Writer。把OutputStream转换成Writer之后就可以一个字符一个字符地通过管道写入数据了

转换流测试代码

import java.io.*;
public class TestTransform1 {
public static void main(String args[]) {
try {
OutputStreamWriter osw = new OutputStreamWriter(
new FileOutputStream("D://kou.txt"));
osw.write("MircosoftsunIBMOracleApplet");// 把字符串写入到指定的文件
中去
System.out.println(osw.getEncoding());// 使用getEncoding()方法取得
当前系统的默认字符编码
osw.close();
osw = new OutputStreamWriter(new FileOutputStream(
"D://kou.txt", true), "ISO8859_1");
// 如果在调用FileOutputStream的构造方法时没有加入true,那么新加入的字符
串就会替换掉原来写入的字符串,在调用构造方法时指定了字符的编码
osw.write("MircosoftsunIBMOracleApplet");// 再次向指定的文件写入字符
串,新写入的字符串加入到原来字符串的后面
System.out.println(osw.getEncoding());
osw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

数据流

  • DataInputStream 和 DataOutputStream 分别继承自InputStream 和 OutputStream , 它属于处理流,需要分别“套接”在InputStream 和 OutputStream类型的节点流上。
  • DataInputStream 和 DataOutputStream 提供了可以存取与机器无关的Java原始类型数据(int,double等)的方法。
  • DataInputStream 和 DataOutputStream 的构造方法
DataInputStream (InputStream in)
DataOutputStream (OutputStream out)

数据流测试代码

package com.kou.chapter;
import java.io.*;
public class TestDataStream{
public static void main(String args[]){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//在调用构造方法时,首先会在内存里面创建一个ByteArray字节数组
DataOutputStream dos = new DataOutputStream(baos);
//在输出流的外面套上一层数据流,用来处理int,double类型的数
try{
dos.writeDouble(Math.random());//把产生的随机数直接写入到字节数组
ByteArray中
dos.writeBoolean(true);//布尔类型的数据在内存中就只占一个字节
ByteArrayInputStream bais = new
ByteArrayInputStream(baos.toByteArray());
System.out.println(bais.available());
DataInputStream dis = new DataInputStream(bais);
System.out.println(dis.readDouble());//先写进去的就先读出来,调用
readDouble()方法读取出写入的随机数
System.out.println(dis.readBoolean());//后写进去的就后读出来,这里面
的读取顺序不能更改位置,否则会打印出不正确的结果
dos.close();
bais.close();
}catch(Exception e){
e.printStackTrace();
}
}
}

通过bais这个流往外读取数据的时候,是一个字节一个字节地往外读取的,因此读出来的数据无法判断是字符串还是bool类型的值,因此要在它的外面再套一个流,通过dataInputStream把读出来的数据转换就可以判断了。读取数据的时候是先写进去的就先读出来,因此读ByteArray字节数组数据的顺序应该是先把占8个字节的double类型的数读出来,然后再读那个只占一个字节的boolean类型的数,因为double类型的数是先写进数组里面的,读的时候也要先读它。这就是先写的要先读。如果先读Boolean类型的那个数,那么读出来的情况可能就是把double类型数的8个字节里面的一个字节读了出来。

打印流(Print)

  • PrintWriter 和 PrintStream 都属于输出流,分别针对与字符和字节
  • PrintWriter 和 PrintStream 提供了重载的print
  • Println方法用于多种数据类型的输出
  • PrintWriter和PrintStream的输出操作不会抛出异常,用户通过检测错误状态获取错误信息
  • PrintWriter 和 PrintStream有自动flush功能
PrintWriter(Writer out)
PrintWriter(Writer out,boolean autoFlush)
PrintWriter(OutputStream out)
PrintWriter(OutputStream out,boolean autoFlush)
PrintStream(OutputStream out)
PrintStream(OutputStream out,boolean autoFlush)

测试代码

/*这个小程序是重新设置打印输出的窗口,
* 把默认在命令行窗口输出打印内容设置成其他指定的打印显示窗口
*/
import java.io.*;
public class TestPrintStream{
public static void main(String args[]){
PrintStream ps = null;
try{
FileOutputStream fos = new FileOutputStream("D:\\IDEA\\CODE\\JAVASE\\src\\com\\kou\\chapter\\log.txt");
ps = new PrintStream(fos);//在输出流的外面套接一层打印流,用来控制打印
输出
if(ps != null){
System.setOut(ps);//这里调用setOut()方法改变了输出窗口,以前写
System.out.print()默认的输出窗口就是命令行窗口
//但现在使用System.setOut(ps)将打印输出窗口改成了由ps指定的文件里
面,通过这样设置以后,打印输出时都会在指定的文件内打印输出
//在这里将打印输出窗口设置到了log.txt这个文件里面,所以打印出来的内容会
在log.txt这个文件里面看到
}
for(char c=0;c<=1000;c++){
System.out.print(c+"\t");//把世界各国的文字打印到log.txt这个文件
中去
}
}catch(Exception e){
e.printStackTrace();
}
}
}

对象流(Object)

直接将Object 写入或读出

  • transient关键字(transient:透明的)用它来修饰的成员变量在序列化的时候不予考虑,也就是当成不存在。
  • serializable接口
  • externaliazble接口
package com.kou.chapter;
import java.io.*;
public class TestObjectIo {
public static void main(String args[]) {
T t = new T();
t.k = 8;// 把k的值修改为8
try {
FileOutputStream fos = new FileOutputStream(
"D:\\IDEA\\CODE\\JAVASE\\src\\com\\kou\\chapter\\TestObjectIo.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
// ObjectOutputStream流专门用来处理Object的,在fos流的外面套接
ObjectOutputStream流就可以直接把一个Object写进去
oos.writeObject(t);// 直接把一个t对象写入到指定的文件里面
oos.flush();
oos.close();
FileInputStream fis = new FileInputStream(
"D:\\IDEA\\CODE\\JAVASE\\src\\com\\kou\\chapter\\TestObjectIo.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
// ObjectInputStream专门用来读一个Object的
T tRead = (T) ois.readObject();
// 直接把文件里面的内容全部读取出来然后分解成一个Object对象,并使用强制转换
成指定类型T
System.out.print(tRead.i + "\t" + tRead.j + "\t" + tRead.d +
"\t"
+ tRead.k);
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/*
* 凡是要将一个类的对象序列化成一个字节流就必须实现Serializable接口
* Serializable接口中没有定义方法,Serializable接口是一个标记性接口,用来给类作标记,
只是起到一个标记作用。
* 这个标记是给编译器看的,编译器看到这个标记之后就可以知道这个类可以被序列化 如果想把某个
类的对象序列化,就必须得实现Serializable接口
*/
class T implements Serializable {
// Serializable的意思是可以被序列化的
int i = 10;
int j = 9;
double d = 2.3;
int k = 15;
// transient int k = 15;
// 在声明变量时如果加上transient关键字,那么这个变量就会被当作是透明的,即不存在。
}

直接实现Serializable接口的类是JDK自动把这个类的对象序列化,而如果实现public interfaceExternalizable extends Serializable的类则可以自己控制对象的序列化,

能让JDK自己控制序列化的就不要让自己去控制

 

部分图片来源:百度图片

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寇大大

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值