首页 > 编程 > Java > 正文

JAVA IO 流整理

2019-11-08 03:22:37
字体:
来源:转载
供稿:网友

一、流的概念

流(stream)的概念源于UNIX中管道(pipe)的概念。在UNIX中,管道是一条不间断的字节流,用来实现程序或进程间的通信,或读写外围设备、外部文件等。

       一个流,必有源端和目的端,它们可以是计算机内存的某些区域,也可以是磁盘文件,甚至可以是Internet上的某个URL。

        流的方向是重要的,根据流的方向,流可分为两类:输入流和输出流。用户可以从输入流中读取信息,但不能写它。相反,对输出流,只能往输入流写,而不能读它。

       实际上,流的源端和目的端可简单地看成是字节的生产者和消费者,对输入流,可不必关心它的源端是什么,只要简单地从流中读数据,而对输出流,也可不知道它的目的端,只是简单地往流中写数据。 

       形象的比喻——水流 ,文件======程序 ,文件和程序之间连接一个管道,水流就在之间形成了,自然也就出现了方向:可以流进,也可以流出.便于理解,这么定义流: 流就是一个管道里面有流水,这个管道连接了文件和程序。

二、流的分类

java中的流,可以从不同的角度进行分类。

     1)按照数据流的方向不同可以分为:输入流和输出流。

     2)按照处理数据单位不同可以分为:字节流和字符流。

    3)按照实现功能不同可以分为:节点流和处理流。

a)输出流:

b)输入流:

因此输入和输出都是从程序的角度来说的。

字节流:一次读入或读出是8位二进制。

字符流:一次读入或读出是16位二进制。

字节流和字符流的原理是相同的,只不过处理的单位不同而已。后缀是Stream是字节流,而后缀是Reader,Writer是字符流。 c)节点流:直接与数据源相连,读入或读出。

Java流类图结构:

Jdk提供的流继承了四大类:InputStream(字节输入流),OutputStream(字节输出流),Reader(字符输入流),Writer(字符输出流)。

InputStream字节输入流:

OutputStream字节输出流:

Reader字符输入流:

Writer字符输出流:

简单介绍其上图:

a)对文件进行操作:FileInputStream(字节输入流),FileOutputStream(字节输出流),FileReader(字符输入流),FileWriter(字符输出流)

b)对管道进行操作:PipedInputStream(字节输入流),PipedOutStream(字节输出流),PipedReader(字符输入流),PipedWriter(字符输出流)PipedInputStream的一个实例要和PipedOutputStream的一个实例共同使用,共同完成管道的读取写入操作。主要用于线程操作。

c)字节/字符数组:ByteArrayInputStream,ByteArrayOutputStream,CharArrayReader,CharArrayWriter是在内存中开辟了一个字节或字符数组。

d)Buffered缓冲流::BufferedInputStream,BufferedOutputStream,BufferedReader,BufferedWriter,是带缓冲区的处理流,缓冲区的作用的主要目的是:避免每次和硬盘打交道,提高数据访问的效率。

e)转化流:InputStreamReader/OutputStreamWriter,把字节转化成字符。

f)数据流:DataInputStream,DataOutputStream。因为平时若是我们输出一个8个字节的long类型或4个字节的float类型,那怎么办呢?可以一个字节一个字节输出,也可以把转换成字符串输出,但是这样转换费时间,若是直接输出该多好啊,因此这个数据流就解决了我们输出数据类型的困难。数据流可以直接输出float类型或long类型,提高了数据读写的效率。

g)打印流:PRintStream,printWriter,一般是打印到控制台,可以进行控制打印的地方。

h)对象流:ObjectInputStream,ObjectOutputStream,把封装的对象直接输出,而不是一个个在转换成字符串再输出。

j)序列化流:SequenceInputStream。

k)对象序列化:把对象直接转换成二进制,写入介质中。使用对象流需要实现Serializable接口,否则会报错。而若用transient关键字修饰成员变量,不写入该成员变量,若是引用类型的成员变量为null,值类型的成员变量为0。

三、字节流的输入与输出的对应

图中蓝色的为主要的对应部分,红色的部分就是不对应部分。紫色的虚线部分代表这些流一般要搭配使用。从上面的图中可以看出Java IO 中的字节流是极其对称的。“存在及合理”我们看看这些字节流中不太对称的几个类吧!1.LineNumberInputStream 主要完成从流中读取数据时,会得到相应的行号,至于什么时候分行、在哪里分行是由改类主动确定的,并不是在原始中有这样一个行号。在输出部分没有对应的部分,我们完全可以自己建立一个LineNumberOutputStream,在最初写入时会有一个基准的行号,以后每次遇到换行时会在下一行添加一个行号,看起来也是可以的。好像更不入流了。

2.PushbackInputStream 的功能是查看最后一个字节,不满意就放入缓冲区。主要用在编译器的语法、词法分析部分。输出部分的BufferedOutputStream 几乎实现相近的功能。

3.StringBufferInputStream 已经被Deprecated,本身就不应该出现在InputStream 部分,主要因为String 应该属于字符流的范围。已经被废弃了,当然输出部分也没有必要需要它了!还允许它存在只是为了保持版本的向下兼容而已。

4.SequenceInputStream 可以认为是一个工具类,将两个或者多个输入流当成一个输入流依次读取。完全可以从IO 包中去除,还完全不影响IO 包的结构,却让其更“纯洁”――纯洁的Decorator 模式。

5.PrintStream 也可以认为是一个辅助工具。主要可以向其他输出流,或者FileInputStream 写入数据,本身内部实现还是带缓冲的。本质上是对其它流的综合运用的一个工具而已。一样可以踢出IO 包!System.out 和System.out 就是PrintStream 的实例!

四、字符流的输入与输出的对应

五、java IO操作

Java的IO类操作主要包括如下几类 1、File类的使用。 2、字节操作流:OutputStream、InputStream 3、字符操作流:Reader、Writer 4、对象序列化:serializable

(A)File类

public class File extends Object implements Serizliable Comparable<File>  

从定义看,File类是Object的直接子类,同时它继承了Comparable接口可以进行数组的排序。File类的操作包括文件的创建、删除、重命名、得到路径、创建时间等,以下是文件操作常用的函数。

File类的操作:(1)创建文件,注意File.separator可以解决跨操作系统的问题。        下面的例子是一创建一个文件,如果该文件存在则删除,否则创建该文件。

public class FileDemo1 {       public static void main(String[] args) {           File file = new File("D:" + File.separator + "test.txt");           if (file.exists()) {               file.delete();           } else {               try {                   file.createNewFile();               } catch (IOException e) {                   // TODO Auto-generated catch block                   e.printStackTrace();               }           }       }   }  (2)文件的类型函数       file.isFile(); //判断是不是文件       file.isDirectory();//判断是不是目录(3)列出目录的内容        pulbic String[] list();//列出所有文件名和目录名        public File[] listFiles();//列出所有文件和目录

(B)字节操作流(btyle) (1)字节输出流OutputStream

public class FileDemo1 {       public static void main(String[] args) {           File file = new File("D:" + File.separator + "test.txt");//指定要操作的文件           OutputStream out=null;//定义字节流输出对象           try {               //out= new FileOutputStream(file,true);//是否字节追加函数               out= new FileOutputStream(file);//获取实际的字节流输出对象,内容覆盖           } catch (FileNotFoundException e) {               e.printStackTrace();           }           String  info="hello";//要输入的内容           byte[] b=info.getBytes();//将字符转化为字节数组           try {               out.write(b);           } catch (IOException e) {               e.printStackTrace();           }           try {               out.close();           } catch (IOException e) {               e.printStackTrace();           }       }   }  

(2)字节输入流InputStream

public class FileDemo1 {       public static void main(String[] args) {           File file = new File("D:" + File.separator + "test.txt");//指定要操作的文件           InputStream In=null;//定义字节流输入对象           try {               //out= new FileOutputStream(file,true);//是否字节追加函数               In= new FileInputStream(file);//获取实际的字节流输入对象           } catch (FileNotFoundException e) {               e.printStackTrace();           }           int len=0;//输入数组长度           byte[] b=new byte[1024];//开辟空间,读取内容           //byte[] b=new byte[(int)file.length()];//根据文件大小开辟空间           try {               len=In.read(b);//读取           } catch (IOException e1) {               e1.printStackTrace();           }           try {               In.close();           } catch (IOException e) {               e.printStackTrace();           }           System.out.println(new String(b,0,len));       }   }(3)字符输出流Write

public class FileDemo1 {       public static void main(String[] args) {           File file = new File("D:" + File.separator + "test.txt");// 指定要操作的文件           Writer write = null;// 定义字符输出流           try {               write = new FileWriter(file);           } catch (IOException e) {               e.printStackTrace();           }           String infor = "hello,heiehiehieh";           try {               write.write(infor);           } catch (IOException e) {               e.printStackTrace();           }           try {               write.close();           } catch (IOException e) {               e.printStackTrace();           }       }   }  

(4)字符输入流Reader

public class FileDemo1 {       public static void main(String[] args) {           File file = new File("D:" + File.separator + "test.txt");// 指定要操作的文件           Reader read = null;// 定义字符输入流           try {               read = new FileReader(file);           } catch (IOException e) {               e.printStackTrace();           }           String infor = "hello,heiehiehieh";           char[] b=new char[1024];//设置字符的长度           try {               int len=read.read(b);           } catch (IOException e) {               e.printStackTrace();           }           try {               read.close();           } catch (IOException e) {               e.printStackTrace();           }       }   }  (5)字节流和字符流的区别(重点)      字节流没有缓冲区,是直接输出的,而字符流是输出到缓冲区的。因此在输出时,字节流不调用colse()方法时,信息已经输出了,而字符流只有在调用close()方法关闭缓冲区时,信息才输出。要想字符流在未关闭时输出信息,则需要手动调用flush()方法。(6)转换流:在io中还存在一类是转换流,将字节流转换为字符流,同时可以将字符流转化为字节流。OutputStreamWriter(OutStream out):j将字节流以字符流输出。InputStreamReader(InputStream in):将字节流以字符流输入。(7)打印流 PrintStream      在操作中要求输出信息时,可以采用PrintStream进行输出,它包括PrintWrite和PrintReader

(C)对象序列化       对象序列化是指将一个对象可以转化为二进制的byte流,可以以文件的方式进行保存。       将对象保存在文件的操作叫做对象的序列化操作。       将对象从文件中恢复的操作叫做反序列化操作。一个对象如果要能序列化,它必须继承Serizliable。在实现序列化是则需要ObjectOurputStream完成,而需要反序列化时则采用ObjectInputStream。

transient关键字:变量声明为Transient后,该变量不可序列化。

 (D)内存流        在项目的开发过程中,有时希望只产生临时文件,将信息输出的内存中,此时会用到内存流,内存流基本方法如下:

public class FileDemo1 {       public static void main(String[] args) {           String infor = "hello";           // 所有的内容向内存中输入           InputStream input = new ByteArrayInputStream(infor.getBytes());           // 所有内存的内容由outputStream输出           OutputStream out = new ByteArrayOutputStream();           int temp = 0;           try {               while ((temp = input.read()) != -1) {                   char c = Character.toUpperCase((char) temp);                   out.write(c);//从内存中输出,所有的内容都保存在ByteArrayOutputStream中               }           } catch (IOException e) {               e.printStackTrace();           }           try {               input.close();           } catch (IOException e) {               e.printStackTrace();           }           try {               out.close();           } catch (IOException e) {               e.printStackTrace();           }           System.out.println(out.toString());       }   }  

(E)System类对IO的支持

(F)缓存读取


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表