Java基础日记———IO流(上)

原创 2015年07月07日 10:04:11

一.概述
1.IO流用来处理设备之间的数据传输 。
2.Java对数据的操作是通过流的方式。
3.Java用于操作流的对象都在IO包中。
4.流按操作数据分为两种:字节流与字符流。
编码表进程:ASCII–>GB2312(中)–>GBK(中)–>Unicode(各个国家的进行重新编排,两个字节表示)–>UTF-8
–>仅为时间关系,不含其他。各个表的编码方式不同。
字符流就是为了适应编码表的多样化,可以指定处理文字是按照的编码表。
5.流按流向分为:输入流,输出流。
IO流常用基类:
字节流抽象基类:InputStream,OutputStream
字符流抽象基类:Reader,Wirter
由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
二.IO体系
1.字符流
(1)抽象类write:创建并写入文件。以操作文本文件来演示:FileWriter
①writer写文件
代码示例:

 FileWriter fw = new FileWriter("demo.txt");//创建一个FileWriter对象,并且对象一被初始化必须明确要操作的文件。
    fw.write("asdasdasd");//调用write方法。
    fw.flush();//刷新缓冲区,将数据存入“目的地”
    fw.close();//关闭流资源(必需操作)。

注意点:
FileWriter初始化文件后将会创建到指定的目录下,如果该目录下存在该文件,那么原文件将会被覆盖。
flush和close的区别:flush只是刷新缓冲区,流可以继续使用;但是,close操作在刷新缓冲区后,将会关闭流资源。
②续写文件:
FileWriter(String fileName, boolean append):根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象。
代码示例:

  FileWriter fw = new FileWriter("demo.txt",true); 
③异常处理:
    第一种直接抛出异常:throws IOException;
    第二种使用try/catch:
    FileWriter fw = null; //在这里声明是因为这样finally中才不报错。
    try  { 
             fw = new FileWriter("demo.txt");
             fw.write("abcdefg");
         } catch (IOException e) { 
              System.out.println("catch:"+e.toString());
         } finally { 
              try { 
                      if(fw!=null) //为了健壮性,判断fw是否为空
                      fw.close();    //必须操作,可以放在finally中
              } catch (IOException e) { 
                    System.out.println(e.toString());
              }   
         }
(2)抽象类Reader:读文件
①读文件
读取方式一

代码示例:

    FileReader fr = new FileReader("demo.txt"); //创建对象
        int c= 0;
        while((c = fr.read())!=-1){
           System.out.print((char)c);
     }
     fr.close();

注意点:
创建一个文件读取流对象,需要和指定名称的文件相关联。而且保证文件存在,否则报错。
read():一次读一个字符。而且会自动往下读。
read的返回值:作为整数读取的字符,范围在 0 到 65535 之间 (0x00-0xffff),如果已到达流的末尾,则返回 -1 。
读取方式二:通过字符数组进行读取。

    FileReader fr = new FileReader("demo.txt");
       char[] buf = new char[1024]; 
       int num = 0;
       while((num=fr.read(buf))!=-1) { 
            System.out.println(new String(buf,0,num));
      }
      fr.close();
注意点:
      定义一个字符数组。用于存储读到的字符。
      该read(char[])返回的是读到字符个数即定义时char的个数,读到最后会返回-1。

小例子
·复制文件主要代码示例:

      FileReader fr2 = new FileReader("demo.txt");
       FileWriter fw = new FileWriter("F:\\demo3.txt");
       char[] ch = new char[2048];
       while(fr2.read(ch)!=-1){
             fw.write(ch);
       }
       fr2.close();
       fw.close(); 

(3)字符流缓冲区
目的:缓冲区是为了提高流的读取效率,所以没有空参数的构造函数。而且创建缓冲区前必须要先有流对象。
原理:缓冲区对象里封装了数组,先把数据存储起来编程一个对象,在进行读写。
①BufferWreiter
代码示例:

FileWriter fw = new FileWriter("buf.txt");  //创建一个字符写入流对象
        BufferedWriter bufw = new BufferedWriter(fw); //将流对象传递给缓冲区构造函数即可
        bufw.write("asdas\r\ndasd"); //写入操作
        bufw.flush();//写入都要刷新
        bufw.close();//关闭的是缓冲区的流对象,所以不用fw.close();
特有方法:
    newLine():写入一个行分隔符。
    方便跨平台使用:在windows中换行是\r\n,而Linux中是\r。

②BufferReader

  FileReader fr = new FileReader("buf.txt");  //创建一个读取流对象  
    BufferedReader bubr = new BufferedReader(fr);
    String s = null;
    while((s=bubr.readLine())!=null){
        System.out.println(s);
    }
    bubr.close();
特有方法:
    readLine():读取一行。
    readLine读取的返回值是String类型,当返回null是为文件的结尾。
    readLine只返回回车符之前的内容,并不包含每行的结尾换行符。
③装饰设计模式:
    当想要对已有的对象进行功能增强时,
    可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。
    那么自定义的该类称为装饰类。
    装饰类通常会通过构造方法接收被装饰的对象。 
    并基于被装饰的对象的功能,提供更强的功能。
装饰类设计模式与继承的区别:
    MyReader//专门用于读取数据的类。
     |--MyTextReader
          |--MyBufferTextReader
     |--MyMediaReader
          |--MyBufferMediaReader
     |--MyDataReader
          |--MyBufferDataReader
    class MyBufferReader
    {
        MyBufferReader(MyTextReader text)
         {}
         MyBufferReader(MyMediaReader media)
         {}
    }
    上面这个类扩展性很差。
    找到其参数的共同类型。通过多态的形式。可以提高扩展性。
    class MyBufferReader extends MyReader
    {
         private MyReader r;
         MyBufferReader(MyReader r)
         {}
    }
    MyReader//专门用于读取数据的类。
         |--MyTextReader
         |--MyMediaReader
         |--MyDataReader
         |--MyBufferReader
    以前是通过继承将每一个子类都具备缓冲功能。
    那么继承体系会复杂,并不利于扩展。
    现在优化思想。单独描述一下缓冲内容。
    将需要被缓冲的对象。传递进来。也就是,谁需要被缓冲,谁就作为参数传递给缓冲区。
    这样继承体系就变得很简单。优化了体系结构。
    装饰模式比继承要灵活。避免了继承体系臃肿。
    而且降低了类于类之间的关系。
    装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。
    所以装饰类和被装饰类通常是都属于一个体系中的。

包装类示例:
LineNumberReader(Reader in):使用默认输入缓冲区的大小创建新的行编号 reader。

2.字节流
    字符流也是字节流,只有多了一个字符的编码表。
    与字节流类似,相同部分只代码示例;不同部分会重点介绍。
(1)OutputStream:字节输出流

代码示例:

 FileOutputStream fos = new FileOutputStream("fos.txt");
    fos.write("abcde".getBytes()); //不用刷新                   
    fos.close();
(2)InputStream:字节输入流

代码示例:

     FileInputStream fis = new FileInputStream("fos.txt");
     int ch = 0;
     while((ch=fis.read())!=-1)
     {
           System.out.println((char)ch);
      }
      fis.close();
   上面的例子是一个一个读字节,比较麻烦。
   可以对其进行修改:定义一个换成数组,一个数组一个数组的往外读取(也就是缓冲区):
    byte[] buf = new byte[1024];
    int len = 0;
    while((len=fis.read(buf))!=-1)
    {
       System.out.println(new String(buf,0,len));
     }
特有方法:
    available():返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)的估计字节数。通俗来讲也就是返回文件的字节数,包括回车符等。
(3)字节流缓冲区

代码示例:

     BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("c:\\0.mp3"));
     BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\1.mp3"));
     int by = 0;
     while((by=bufis.read())!=-1) //返回值是int类型而字符流缓冲区读一行时返回的是String类型
     {
           bufos.write(by);
      }
      bufos.close();
      bufis.close();
3.读取键盘录入 
    (1)通过刚才的键盘录入一行数据并打印其大写,发现其实就是读一行数据的原理。也就是readLine方法。
    readLine方法是字符流BufferedReader类中的方法。而键盘录入的read方法是字节流InputStream的方法。
    那么可以将字节流转换为字符流进行操作,同时方便对字符流操作可以使用缓冲区。
    字节流与字符流之间的桥梁:Reader的子类:
    InputStreamReader(InputStream in):创建一个使用默认字符集的 InputStreamReader。   
    OutputStreamWriter(OutputStream out):创建使用默认字符编码的 OutputStreamWriter      
    获取键盘录入对象。
    InputStream in = System.in;
    将字节流对象转成字符流对象,使用转换流。InputStreamReader
    InputStreamReader isr = new InputStreamReader(in);
    为了提高效率,将字符串进行缓冲区技术高效操作。使用BufferedReader
    BufferedReader bufr = new BufferedReader(isr);
  可以合为一句,即成为键盘录入最常见的写法:BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
    输出与之类似就是:BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));

代码示例:

     BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
      BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
      String line = null;
      while((line=bf.readLine())!=null){
           bw.write(line.toUpperCase());
           bw.newLine();
           bw.flush();
          }
          bf.close();
          bw.close();
     }
(2).最简单,最强大的,就是用Scanner类
  public static void main(String [] args) {
  Scanner sc = new Scanner(System.in);
  System.out.println(“请输入你的姓名:”);
  String name = sc.nextLine();
  System.out.println(“请输入你的年龄:”);
  int age = sc.nextInt();
  System.out.println(“请输入你的工资:”);
  float salary = sc.nextFloat();
  System.out.println(“你的信息如下:”);
  System.out.println(“姓名:”+name+“\n”+“年龄:”+age+“\n”+“工资:”+salary);
  }
4.流操作的基本规律: 
    最痛苦的就是流对象有很多,不知道该用哪一个。
    通过三个明确来完成。
(1)明确源和目的。
     源:输入流。InputStream  Reader
     目的:输出流。OutputStream  Writer。
(2)操作的数据是否是纯文本。
     是:字符流。
     不是:字节流。
(3)当体系明确后,在明确要使用哪个具体的对象。
     通过设备来进行区分:
     源设备:内存,硬盘。键盘
     目的设备:内存,硬盘,控制台。
举例:
(1)将一个文本文件中数据存储到另一个文件中。复制文件。
     源:因为是源,所以使用读取流。InputStream Reader
     是不是操作文本文件。
     是!这时就可以选择Reader
     这样体系就明确了。
     接下来明确要使用该体系中的哪个对象。
     明确设备:硬盘。上一个文件。
     Reader体系中可以操作文件的对象是 FileReader
     是否需要提高效率:是!加入Reader体系中缓冲区 BufferedReader.
     FileReader fr = new FileReader("a.txt");
     BufferedReader bufr = new BufferedReader(fr);
     目的:OutputStream Writer
     是否是纯文本
     是!Writer
     设备:硬盘,一个文件。
     Writer体系中可以操作文件的对象FileWriter
     是否需要提高效率:是!
     加入Writer体系中缓冲区 BufferedWriter

     FileWriter fw = new FileWriter("b.txt");
     BufferedWriter bufw = new BufferedWriter(fw);
(2)需求:将键盘录入的数据保存到一个文件中。
     这个需求中有源和目的都存在。
     那么分别分析
     源:InputStream Reader
     是不是纯文本?是!Reader
      设备:键盘。对应的对象是System.in.
     不是选择Reader吗?System.in对应的不是字节流吗?
     为了操作键盘的文本数据方便。转成字符流按照字符串操作是最方便的。
     所以既然明确了Reader,那么就将System.in转换成Reader。
     用了Reader体系中转换流,InputStreamReader
     InputStreamReader isr = newInputStreamReader(System.in);
     需要提高效率吗?需要!BufferedReader
     BufferedReader bufr = new BufferedReader(isr);
     目的:OutputStream  Writer
     是否是存文本?是!Writer。
     设备:硬盘。一个文件。使用 FileWriter。
     FileWriter fw = new FileWriter("c.txt");
     需要提高效率吗?需要。
     BufferedWriter bufw = new BufferedWriter(fw);

Java基础日记———IO流(下)

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——- 一.概述 1.File: 用来将文件或者文件夹封装成对象。 方便对文件与文件夹的属...

黑马程序员————Java基础日常笔记---IO流二

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 黑马程序员————Java基础日常笔记---IO流二 1.1 File类由来 通过IO流一可...

黑马程序员————Java基础日常笔记---IO流一

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 黑马程序员————Java基础日常笔记---IO流一 1.1 IO的由来: 先什么是IO流呢...

黑马程序员————Java基础日常笔记---IO其他流

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 黑马程序员————Java基础日常笔记---IO其他流 3.1 IO包中的其他类 3.1....

--IO流和文件操作--java学习日记8(基础知识)

IO流分为字符流和字节流两种,当要操作的对象时纯文本文件时,可以用字符流FileReader,要进一步提高效率可用BufferedReader包装一下。比如要拷贝一个文本文件,可以创建一个输入流: ...
  • qq_1991
  • qq_1991
  • 2014年07月18日 15:33
  • 704

Java基础第十八天学习日记_Util包中一些有用的类、IO流

------- android培训、java培训、期待与您交流! ---------- System:类中的方法和属性都是静态的。 常用方法: out:标准输出,默认是控制台。 in:标准...

Java基础日记———Map

——<a href=”http://www.itheima.com” target=”blank”>Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! ——- 一....

Java基础日记———异常

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——- 一.概述 (1)异常:就是程序在运行时出现不正常情况。 异常由来:问题也是现实生活中一个具体的事物...

Java基础日记———网路编程

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——- 一.概述 1.网络模型:OSI参考模型和TCP/IP模型如图: 2.网络通信三要素:IP地址,端口号,传输...

Java基础日记———String

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-一.概述 Java中万物皆对象。 字符串是一个特殊的对象。 字符串一旦初始化就不可以...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java基础日记———IO流(上)
举报原因:
原因补充:

(最多只允许输入30个字)