java学习笔记之IO流总结(一)

来源:互联网 发布:网络订餐食品安全现状 编辑:程序博客网 时间:2024/05/01 13:07

输入输出作为所有程序都必需的部分   对于我们的java学习有特别重要的意义,以至于博主辛苦看了三天的流分布,跟大家分享一下

一.首先我们说一下io流的概念

流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
简单的说这就是计算机传输数据的方式  输入流主要体现在我们从键盘输入传送给计算机,输出流主要体现在计算机在屏幕上打印输出的数据

二.IO流的分类

1.按流的方向分为:输入流和输出流2.按流的数据单位不同分为:字节流和字符流3.按流的功能不同分为:节点流和处理流(过滤流)  节点流:可以从或向一个特定的地方(节点)读写数据。如FileReader 处理流:是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如BufferedReader。处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。

输入流和输出流主要区分的关键字就是Input 和Output 还有Reader和Writer

字节和字符主要区分的关键字是有没有stream,有stream的是字节流,可以传输任何数据,而字节流只能传输文本内容。(有同学淘气的问那OutputStreamWriter什么流呀,当人是字节流,毕竟字节优先级大)

内存中其实就是字节流8位一读,而字符是16位一读。但是double怎么读呢   这个可以看一下DataOutputStream的源代码,里面的就是各种数据类型的读取过程。

节点流

处理流

                                       


这里面最难的就应该是节点流和处理流的区分,首先给大家上一张图

Java IO流学习总结

这张图中列出了我们常用的流类。

常用的节点流
  父 类 :InputStream OutputStream Reader Writer
  文 件 :FileInputStream FileOutputStrean FileReader FileWriter 文件进行处理的节点流
  数 组 :ByteArrayInputStream ByteArrayOutputStream CharArrayReader CharArrayWriter 对数组进行处理的节点流(对应的不再是文件,而是内存中的一个数组)
  字符串 :StringReader StringWriter 对字符串进行处理的节点流
  管 道 :PipedInputStream PipedOutputStream PipedReader PipedWriter 对管道进行处理的节点流

*****************************************************************************************************************************************************************************************
常用处理流(关闭处理流使用关闭里面的节点流)
  父 类 InputStream OutputStream Reader Writer
  缓冲流 *BufferedImputStrean BufferedOutputStream BufferedReader BufferedWriter ----需要父类作为参数构造,增加缓冲功能,避免频繁读写硬盘,可以初始化缓冲数据的大小,由于带了缓冲功能,所以就写数据的时候需要使用flush方法咯
  转换流 *InputStreamReader OutputStreamWriter- 要inputStream或OutputStream作为参数,实现从字节流到字符流的转换
  数据流 *DataInputStream DataOutputStream -提供将基础数据类型写入到文件中,或者读取出来,为什么要有这个流呢?看这样的分析,如果没有这种流的话,有一个long,本身只占8个字节,如果我要写入到文件,需要转成字符串,然后在转成字符数组,那空间会占用很多,但是有了这种流之后就很方便了,直接将这8个字节写到文件就完了。。是不是既节约了内存空间有让程序写起来更加方便简单了呐。写倒是很简单,但是读取的时候就注意了,根据读取的数据类型,指针会往下移,所以你写的顺序必须要和读的顺序一致才能完成你正确的需求。
  *ObjectInputStream ObjectOutputStream
  *顺便研究序列化---将对象所在的类型全部转换成二进制,然后写入到介质中去
  *transient关键字--修饰成员变量,不写入该成员变量
  *Serializable接口--表示接口,怎样实现的呢,在序列化之前,首先判断 (对象 instanceof Serializable)如果返回true则执行序列化,否者抛出异常,并且里面有一个ID,是用来快速查找某个对象的时候使用的
  *Externalizable接口--外部化接口;他是Serializable接口的子接口,能手动控制序列化的方式
  为什么要用writeUTF()--因为这种方式是按照utf-8来写入的,而默认方式是utf-16只是节省空间而已
  --字节流读取中文的问题
  *由于Java使用的是unicode编码,每一个中文字符是占用两个字节的,所以没有只读出其中一个字节并使用的话当然是乱码咯,虽然普通的英文字符也是两个字节的,但是读取的时候将高8位去掉也能回去正确的英文字符,所以没有问题,所以最好还是使用字符流的方式读取好点
  --java.io中专门提供用于打印的流(这类流在写入的时候有自动flush的功能,所以你不需要每打印一个东西都flush一次)--------注意他们也是属于处理流,只不过这里单独列出来分析而已
  *PrintStream--继承自-->FilterOutputStream--继承自-->OutputStream,(它的构造函数需要OutputStream对象)

一般的定义方式大概是这个样子的:

PrintWriter pw = new PrintWriter(//最外层是处理流new OutputStreamWriter(new FileOutputStream("E:\\imooc\\2.txt",true)));

*PrintWriter---继承自-->Writer(它的构造函数需要Writer对象)

  System.In====InputStream

  System.Out===PrintStream

接下来给大家举几个例子:

1.通过Scanner读两句话,并写到一个文件中.通过PrintWriter来实现

public static void main(String[] args) throws IOException{Scanner reader = new Scanner(System.in);System.out.print("请输入第一句话:");String fir = reader.nextLine();System.out.print("请输入第二句话:");String sed = reader.nextLine();PrintWriter pw = new PrintWriter(new (new FileOutputStream("E:\\imooc\\2.txt",true)));pw.println(fir);pw.println(sed);pw.flush();pw.close();}
上述代码如果输入中文字符就会出现问题,因为中文的编码是2个字节一个汉字,而PrintWriter的父类是OutputStream相当于输出方式是字节编码,所以会发生意想不到的错误。

2.使用FileOutputStream,向"f:/output" 输出一句话"hello world",并能过FileInputStream流读出这段文字

public static void put(String targerName){try(FileOutputStream f2 = new FileOutputStream(targerName);FileInputStream f1 = new FileInputStream(targerName);){f2.write("hello world".getBytes());//byte[] b = new byte[];int len = -1;    while((len=f1.read()) != -1){    System.out.print((char)len);}        } catch (IOException e) {e.printStackTrace();}}public static void main(String[] args){put("E:\\JAVA\\新建文件夹\\新建文件夹\\新建文件夹\\新建文本文档.txt");}
3.将Student对象转换成byte[],并将些byte数据写到文件中,再写一个程序读出此byte数组,将此byte数组转换成Student.
Student类
public class Student implements Serializable{   <span style="white-space:pre"></span>private static final long serialVersionUID = -5809782578272943999L;<span style="white-space:pre"></span>Date brith;<span style="white-space:pre"></span>String name;<span style="white-space:pre"></span>int height;<span style="white-space:pre"></span>String degree;<span style="white-space:pre"></span>public Student(Date brith, String name, int height, String degree) {<span style="white-space:pre"></span>super();<span style="white-space:pre"></span>this.brith = brith;<span style="white-space:pre"></span>this.name = name;<span style="white-space:pre"></span>this.height = height;<span style="white-space:pre"></span>this.degree = degree;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>public Student(){<span style="white-space:pre"></span><span style="white-space:pre"></span>}
}
读入数组public static void main(String[] args) throws Exception{Student s1 = new Student(new Date(System.currentTimeMillis()),"马云",42,"土豪");File file = new File("demo/student.txt");FileOutputStream fos = new FileOutputStream(file);byte[] bytes;ByteArrayOutputStream bo = new ByteArrayOutputStream();          ObjectOutputStream oo = new ObjectOutputStream(bo);         oo.writeObject(s1);        bytes=bo.toByteArray();        fos.write(bytes, 0, bytes.length);        fos.close();        bo.close();        oo.close();}从数组读出        public static void main(String[] args) throws Exception{File file = new File("demo/student.txt");FileInputStream fis = new FileInputStream(file);byte[] bytes =new byte[1024];int len = 0;while((len=fis.read(bytes))!=-1); ByteArrayInputStream bi = new ByteArrayInputStream(bytes);  ObjectInputStream oi = new ObjectInputStream(bi);  Student s = (Student)oi.readObject();System.out.println(s);bi.close();  oi.close();  }
这几个程序用的流不是特别常见,所以拿出来分享一下。

如果有什么见解或者有什么写的有问题的地方可以在下面留言,欢迎大家一起学习一起进步


1 0
原创粉丝点击