java的IO流

    xiaoxiao2023-11-19  154

    1、分类

    A.按方向分:         输入流:比如从文件到程序         输出流:比如从程序到文件

    B.按单位分:         字节流:每次进行读写时操作的最小单位是一个字节,继承于InputStream和 OutputStream         字符流:每次进行读写时操作的最小单位是一个字符 继承于InputStreamReader和 OutputStreamWriter

            注意:字符流只能处理字符数据,字节流可以处理所有类型数据,如图片,MP3,AVI视频文件,故只要处理纯文本数据,优先考虑使用字符流,初次之外都用字节流。

    C.按功能分:         节点流(底层流):直接连接起点和终点的流,如FileReader         过滤流(包装流):不直接连接起点和终点,而是直接连接节点流,如BufferedReader

    图片来源:https://www.cnblogs.com/thinksasa/archive/2012/10/26/2741091.html

     对比上图需要学习的几个主要父类:    

      Reader:字符输入流(把从记事本读到的内容显示到操作台)      Writer:字符输出流(写入到记事本)      InputStream      字节输入流  OutputStream    字节输出流

    字符与字节的关系

            不同编码里,字符和字节的对应关系不同:

    编码英文(字节)中文(字节)ASCII码12UTF-813Unicode22

    2、字符流的使用

          1、 常用的字符流

         (1)Reader和 Writer(抽象类)

                    Reader是用来读出数据的,是所有处理字符流的输入类的父类, Writer是用来输出数据的,是所有处理字符流的输出类的父类

         (2) FileReader和 FileWriter

                    FileReader和 FileWriter分别是抽象类Reader类和 Writer类的子类,以字符为单位进行数据读/写操作,数据的传输效率很低

          (3)BufferedWriter和BufferedReader

                   学这两个流的目的是为了他们中强大的api,他们是以缓冲流方式对数据进行读/写操作。

                     A.)BufferedWriter:字符缓冲输出流              newLine():换行                  B.)BufferedReader:字符缓冲输入流            readLine():每次读一行

         注意:         A.字符流天生自带缓冲区,就是你写入的数据不是直接发送到目的地,而是先把数据存入缓冲区里,最后再从缓冲区,把数据发送到目的地。 (缓冲区就是积攒数据的地方,是为了减少读写的次数,从而提高读写的速度 )    

          B.字符流只能操作文本文件,(文本文件就是能用记事本打开,并且不会乱码的文件)。

    2、程序示例:

    例1:利用字符流实现文件的简单读和写  

    public abstract class Demo03 { public static void main(String[] args) throws IOException { //字符输出流: /*Writer out=new FileWriter("f:/a.txt"); out.write(97); out.write('a'); out.close(); System.out.println("over");*/ //字符输入流 Reader in=new FileReader ("f:/a.txt"); int a; while((a=in.read())!=-1) { System.out.print(" "+a); } System.out.println(" over"); } }

    结果:

    程序上半部分为字符输出到f盘下的a.txt文件,可以发现文件中输出“aa”,再从f盘下的a.txt将内容读出,结果为97 97 over。

    例2:利用字符流实现文件的复制

    public abstract class Demo03 { public static void main(String[] args) throws IOException { //字符输出流: Reader in=new FileReader ("f:/a.txt"); Writer out=new FileWriter("f:/b.txt"); int a; char[] b=new char[100];//这里如果把char[100]改为char[1],则往b里复制内容的速度将会变慢 while((a=in.read(b))!=-1) { out.write(b,0,a); } out.close();//这里一定要记着关流,否则文件内容会存放在缓冲区,无法正常显示 in.close(); System.out.println("over"); } }

    注意:

    FileReader在读取文件内容的时候,我们传入文件的路径("f:/a.txt"), 如果这个路径下的文件不存在,那么在执行read()方法时会报FileNotFoundException异常。FileWriter在写入文件的时候,我们传入文件的路径("f:/a.txt"), 如果这个路径下的文件不存在,那么在执行writeFile()方法时, 会默认给我们创建一个新的文件,不会报异常。

    例3:利用字符缓冲输出流BufferWriter实现写换行               BufferWriter.newLine();

    public abstract class Demo03 { public static void main(String[] args) throws IOException { Writer out=new FileWriter("f:/b.txt"); BufferedWriter br=new BufferedWriter(out); br.write("哈哈哈"); br.newLine(); br.write("嘻嘻嘻"); br.close(); System.out.println("over"); } }

    例4:利用字符缓冲输入流BufferedReader实现写换行               BufferedReader.readLine();

    public abstract class Demo03 { public static void main(String[] args) throws IOException { Reader in=new FileReader ("f:/b.txt"); BufferedReader br=new BufferedReader(in); String a; a=br.readLine(); //readLine():每次读一行,不用考虑字符串长度 System.out.println(a); a=br.readLine(); System.out.println(a); } }

    输出:

    哈哈哈 嘻嘻嘻

     

     

    3、字节流的使用

    1、常用的字节流

    (1)InputStream和 OutputStream

             二者都是抽象类是表示输入/输出字节流的所有类的超类。

    (2)FileInputStream和 FileOutputStream

             FileInputStream和 FileOutputStream分别是抽象类InputStream和 OutputStream类的子类,以字节为单位进行数据读/写操作

    (3)BufferedInputStream和BufferedouputStream

           字节缓冲流,使用这两个缓冲流不为别的,就看上了他的缓冲区

    (4)DataInputStream和DataOutputStream

            数据输入/出流,使用这两个缓冲流的目的就是为了读写8种基本数据类型;这两个流以什么样的顺序流入,就要以什么样的数据流出

    (5)ObjectInputStream和ObjectOutputStream

            对象输出流,这是专门用来操作一个对象的,自己定义的类必须实现序列化接口,才能被对象数据流所操作, 系统内置的类基本都实现了序列化接口。

    (6)InputStreamReader和OutputStreamWriter

           转换流,InputStreamReader字节输入流转成字符输入流,该类的构造函数可以传入InputStream对象;OutputStreamWriter字节输出流转成字符输出流,该类的构造函数可以传入OutputStream对象。

    (7)System.in和System.out

    标准流,System.in标准输入是键盘;System.out标准输出是屏幕

    注意:

     A.字节流是没有缓冲区的,直接会写入目的地

    B字符过滤流只能包装字符流,字节过滤流只能包装字节流,混用会报错

     

    2、程序示例:

    例1:利用字节流实现文件的简单读和写 

    //把记事本a里的“移动”两个字输入到显示台 public abstract class Demo03 { public static void main(String[] args) throws IOException { InputStream in=new FileInputStream("f:/a.txt"); byte[] b=new byte[3];//记事本和eclipse都用的utf-8编码 int n; while(( n=in.read(b))!=-1) { System.out.println(new String(b)); } } }

    例2:利用字节流实现图片复制

    public abstract class Demo03 { public static void main(String[] args) throws IOException { InputStream in=new FileInputStream("f:/1.jpg"); OutputStream out=new FileOutputStream("f:/2.jpg"); byte[] b=new byte[24]; int n; while(( n=in.read(b))!=-1) { out.write(b,0,n); } out.close(); in.close(); System.out.println("over"); } }

    注:因为字节流没有缓冲区,所以就算忘记关流也会输出,但是建议关流节省资源。

    例3:利用字节流,制作下载程序,下载软件

    public class Demo3 { public static void main(String[] args) throws IOException { System.out.println("复制开始"); URL u=new URL("http://cdn4.mydown.com/5bdeab6e/fc3fb296c743a1aef1c4c61a83247778/newsoft/W.P.S.7520.12012.0.exe"); //此时起点来自网络 InputStream in=u.openStream(); OutputStream out=new FileOutputStream("d:/wps.exe"); int n; byte[] b=new byte[1024]; while((n=in.read(b))!=-1){ out.write(b,0,n); } out.close(); in.close(); System.out.println("复制结束"); } }

    例4:利用对象字节流往文件里面写入一个对象

    class People implements Serializable{ private static final long serialVersionUID =1L; transient String name;//属性如果被transient,static关键字修饰,则该属性不会被序列化到文件中 static int age; String sex; public void f1(){} @Override public String toString() { return "People [name=" + name + ", age=" + age + "]"; } } public class Demo03 { public static void main(String[] args) throws IOException, ClassNotFoundException, CloneNotSupportedException { //往文件里面写入一个对象 /*OutputStream out=new FileOutputStream("f:/2.txt"); ObjectOutputStream ops=new ObjectOutputStream(out); People p=new People(); p.name="lisi"; p.age=19; p.sex="M"; ops.writeObject(p); ops.close(); System.out.println("over");*/ InputStream in=new FileInputStream("f:/2.txt"); ObjectInputStream obj=new ObjectInputStream(in); People p1=(People) obj.readObject(); System.out.println(p1.name); System.out.println(p1.age); System.out.println(p1.sex); obj.close(); } }

    输出结果:

    null 0 M

    注意:属性如果被transient,static关键字修饰,则该属性不会被序列化到文件中。

    例4:转换流,字节输入/出流转换成字符输入/出流

    public class Demo03 { public static void main(String[] args) throws Exception { //字节输入节点流 InputStream in=new FileInputStream("f:/a.txt"); //转换流,把字节输入流转换成字符输入流 InputStreamReader isr=new InputStreamReader(in); //字符输入流 BufferedReader br=new BufferedReader(isr); int a; while((a=br.read())!=-1) { System.out.print((char)a); } System.out.println(" over"); } }

    例5:标准流

    public class Demo03 { public static void main(String[] args) throws Exception { Scanner s=new Scanner(System.in); System.out.println(s.next());//等待键盘输入 System.err.print("over"); } }

    输出结果:

     

     

    最新回复(0)