在学习流这部分知识,学的过程并不觉得有很多问题。等到实际运用中发现自己并不能运用自如,这才意识到自己学习知识点没有好好的总结是最大的问题。接下来,我将对所学的IO知识进行一番梳理。
Java中,我们写程序除了自身定义一些数据信息外,经常还会引用 外界的数据,或是将自身的数据发送到 外界。
一、IS与OS
1.按流的方向——输入和输出:对于数据的输入输出操作是以流的形式实现的。
- 输入:用来“读取”数据的
- 输出:用来“写出”数据的
2.按流的功能——节点流和处理流:
- 节点流(低级流):有明确的来源/去向
- 处理流(高级流):建立在另外一个流之上(构造方法总会带上其他一个流对象作为参数),不能独立存在。使用的目的是:为了简化读写操作。
3.按流的数据单位——字节流和字符流
InputStream:所有字节输入流的父类
OutputStream:所有字节输出流的父类
Reader:所有字符输入流的父类
Writer:所有字符输出流的父类
常用方法:
——int read()-----------------------------------------------------(-1)表示EOF
——int read(byte[] b)
——void write(int d)
——void write(byte[] b)
——void write(byte[] b,int offset,int len)
二、文件流(低级流):以字节为单位
访问文件之FileInputStream和FileOutputStream继承基类用于向文件中输入输出字节。
访问文件之FileReader和FileWriter继承基类用于向文件中输入输出字符。
常用方法:
——FileInputStream(File file)
——FileInputStream(String name)
——FileOutputStream(File file)
- ——FileOutputStream(String name) 若指定的文件已经包含内容,那么当使用FOS对其写入数据时,会将该文件原有数据全部清除。
- ——FileOutputStream(File file,boolean append)
- ——FileOutputStream(String name,boolean append) 若不想每次都把前面的清除,那么为true时,使用FOS写出的数据都是在文件末尾追加的。
——输出流在构造函数第二个参数可以设置true意义为跟在已有文件后进行输入。
——此类流会抛出FileNotFoundException需要对其进行显示捕捉。
——int read()--------------------------------(-1)表示EOF
——void write(int d)
——int read(byte[] b)
——int read(char[] chs)
——void write(byte[] d)
——void write(char[] chs)
——void write(String str)
——void write(byte[] d,int offset,int len)
——void write(char[] chs,int offset,int len)-------------------将给定字符数组中从offset处开始连续的len个字符
三、缓冲流(高级流)——记得关流!!!!
缓冲流要套接在相应的节点流之上,提高了读写的效率。
BOS和BIS都是为了读写效率而编写的额外内容,提高读写效率。
BOS实现写出缓冲:缓冲流.close()会自动调用flush()!!!!!!!!!!!package IO; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import org.junit.Test; public class IO { @Test public void testBOS()throws Exception{ FileOutputStream fos = new FileOutputStream("demo01.txt"); //创建缓冲字节输出流 BufferedOutputStream bos = new BufferedOutputStream(fos); //所有字节被存入缓冲区,等待一次性写出 bos.write("helloworld".getBytes()); //关闭流之前,缓冲区输出流会将缓冲区的内容一次性写出 bos.close(); } }
BIS实现输入缓冲:
//运行结果:104 101 108 108 111 119 111 114 108 100package IO; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import org.junit.Test; public class IO { @Test public void testBOS()throws Exception{ FileOutputStream fos = new FileOutputStream("demo01.txt"); //创建缓冲字节输出流 BufferedOutputStream bos = new BufferedOutputStream(fos); //所有字节被存入缓冲区,等待一次性写出 bos.write("helloworld".getBytes()); //关闭流之前,缓冲区输出流会将缓冲区的内容一次性写出 bos.close(); } @Test public void testBIS()throws Exception{ FileInputStream fis = new FileInputStream("demo01.txt"); BufferedInputStream bis = new BufferedInputStream(fis); int d=-1; //缓冲读入,并非是一个字节一个字节从文件读取 while((d=bis.read())!=-1){ System.out.print(d+" "); } bis.close(); } }
BufferedReader:提供了readLine方法用于高校读取一行字符串
——BufferedReader(Reader reader)
——String readLine()-------------------------------------该方法连续读取一行字符串,直到读取到换行符为止,返回的字符串 不包含该换行符。
四、对象流(高级流)—— 一是将对象保存,二是用于传输。
- transient关键字为不序列化此成员变量:
- 需要序列化的类必须实现Serializable接口。-------------实现该接口不用重写任何方法,它只是作为可序列化的标志。
主要方法:
——void writeObject(Object o);(OOS实现对象序列化)
——Object readObject()。(OIS实现对象反序列化)--------------读出为Object类型需要强转数据类型
package IO; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class testObjectIO { public static void main(String[] args) throws IOException, Exception { T t = new T(); t.k =8; FileOutputStream fos = new FileOutputStream("dat.dat"); ObjectOutputStream oos =new ObjectOutputStream(fos); oos.writeObject(t); oos.flush(); oos.close(); FileInputStream fis = new FileInputStream("dat.dat"); ObjectInputStream ois = new ObjectInputStream(fis); T tRead = (T) ois.readObject(); System.out.println(tRead.i + " " + tRead.j + " " + tRead.d + " " + tRead.k); ois.close(); } } class T implements Serializable{ int i=10; int j=9; double d =2.3; transient int k =15; } 运行结果:10 9 2.3 0
五、文件数据IO操作
- 转换流------------------------主要作用将字节流转换成字符流。用处较大!
InputStreamReader需要和InputStream套接
OutputStreamWriter需要和OutputStream套接
例:OutputStreamWriter osw = new OutputStreamWriter (new FileOutputStream(文件路径);
这两个流都可以根据给定的字符集读写字符串!!!!!!!!!!!例:InputStreamReader Isr = new InputStreamReader(fis,"GBK");
使用OSW和ISR:
package IO; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import org.junit.Test; public class IO { @Test public void testOutput()throws IOException{ FileOutputStream fos =new FileOutputStream("demo01.txt"); OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8"); String str = "大家好!"; osw.write(str); osw.close(); } @Test public void testInput()throws IOException{ FileInputStream fis = new FileInputStream("demo01.txt"); InputStreamReader isr = new InputStreamReader(fis,"UTF-8"); int c = -1; while((c=isr.read())!=-1){ System.out.print((char)c); } isr.close(); } }
- Print流
Print流只有输出流无输入流,PrintWriter和PrintStream分别针对字符字节
两个类提供了重载的Print和Println方法用于多种数据类型的输出
PrintWriter和PrintStream的输出操作不会抛出异常
PrintWriter和PrintStream有自动flush功能
----System.setOut(接收OutputStream类):用于设置系统默认输出流
在文件demo01里面写:你们好package IO; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import org.junit.Test; public class IO { @Test public void testPrintWriter()throws IOException{ FileOutputStream fos = new FileOutputStream("demo01.txt"); OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8"); //创建带有自动行刷新的PW PrintWriter pw = new PrintWriter(osw,true); pw.println("你们好"); pw.close(); } }