关闭

Java中IO流学习07

标签: Java学习笔记黑马程序员字符流io流
301人阅读 评论(0) 收藏 举报
分类:

 

一、什么是IO流

IO流用来处理设备之间的数据传输。Java对数据的操作是通过流的方式。Java用于操作流的对象都在IO包中。输入流和输出流相对于内存设备而言。

IO流的分类

根据处理数据类型的不同分为:字符流和字节流。

根据数据流向不同分为:输入流和输出流。

流的分类

1、按功能分 

读取流:InputStream Reader 

写出流:OutPutStream Writer

2、按流的类型分类

字节流:InputStream OutputStream

字符流:Reader    Writer

3、字节流的抽象基类:InputStream,OutputStream。
4、字符流的抽象基类:Reader,Writer。

p.s.

 字符流的由来:
    其实就是:字节流读取文字字节数据后,不直接操作而是先查指定的编码表,获取对应的文字。再对这个文字进行

操作。简单说:字节流+编码表。


二、IO流的运用

重点记忆:

1. close方法只能用一次。

2. 流关闭以后不能,不能再调用write方法,否则会报异常错误。

3.如果构造函数中加入true,可以实现对文件进行续写。

4.IO流的异常处理方式:为防止代码异常导致流无法关闭,因此在finally中对流进行关闭。

5.如果要操作文字数据,建议优先考虑字符流。

读取一个文本文件,有2种方式:

第一种读取方式:使用read()方法读取文本文件数据。


第二种读取方式:使用read(char[])方法读取文本文件数据。

import java.io.FileReader;
import java.io.IOException;

public class FileReaderDemo{
       public static void main(String[] args)throws IOException{
            FileReader fr = new FileReader("demo.txt" );

             //使用read(char[])读取文本文件数据
             //先创建字符数组
             char[] buf = new char[3];

             int len = 0;

             while((len = fr.read(buf)) != -1){
                  System.out.println( new String(buf,0,len));
            }

            fr.close();
      }
}



案例演示1:

将d盘的一个文本文件复制到d盘。

分析:
    读取d盘demo.txt文件中的数据,将这些数据写入到d盘copyText_1.txt文件当中。

    既然是操作文本数据,使用字符流。

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CopyTextTest{
       private static final int BUFFER_SIZE = 1024;

       public static void main(String[] args){
            FileReader fr = null;
            FileWriter fw = null;
            
             try{
                  fr = new FileReader("demo.txt" );
                  fw = new FileWriter("copytest_2.txt" );
                  
                   //创建一个临时容器,用于缓存读取到的字符
                   char[] buf = new char[BUFFER_SIZE];

                   //定义一个变量记录读取到的字符数(其实就是往数组里装的字符个数)
                   int len = 0;

                   while((len = fr.read(buf)) != -1){
                        fw.write(buf,0,len);
                  }
            } catch(Exception e){
                   throw new RuntimeException("读写失败!");
            } finally{
                   if(fw != null){
                         try{
                              fw.close();
                        } catch(IOException e){
                              System.out.println(e.toString());
                        }
                  }
                   if(fr != null){
                         try{
                              fw.close();
                        } catch(IOException e){
                              System.out.println(e.toString());
                        }
                  }
            }
      }
}



三、字符缓冲区

缓冲区的出现提高了对数据的读写效率。

对应类:
   BufferedWriter
   BufferedReader

缓冲区要结合流才可以使用。
作用:在流的基础上对流的功能进行了增强。


1、字符流缓冲区:
    写入换行使用BufferedWriter类中的newLine()方法。
    读取一行数据使用BufferedReader类中的readLine()方法。

    bufr.read():这个read方法是从缓冲区中读取字符数据,所以覆盖了父类中的read方法。
    bufr.readLine():另外开辟了一个缓冲区,存储的是原缓冲区一行的数据,不包含换行符。

    原理:使用了读取缓冲区的read方法,将读取到的字符进行缓冲并判断换行标记,将标记前的缓冲数据变成字符串返回。


案例演示2:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;

public class CopyTextBufTest{
       public static void main(String[] args) throws Exception {
            FileReader fr = new FileReader("buf.txt" );
            BufferedReader bufr = new BufferedReader(fr);

            FileWriter fw = new FileWriter("buf_copy.txt" );
            BufferedWriter bufw = new BufferedWriter(fw);
            
            String line = null;

             //方式一
             while((line = bufr.readLine()) != null){
                  bufw.write(line);
                  bufw.newLine();
                  bufw.flush();
            }

             //方式二
             /*
            int ch = 0;

            while((ch = bufr.read()) != -1){
                  bufw.write(ch);
            }
            */

            bufr.close();
            bufw.close();
      }
}



2、LineNumberReader
   跟踪行号的缓冲字符输入流。此类定义了方法 setLineNumber(int) 和 getLineNumber(),它们可分别用于设置和获取当前行号。

案例演示2:

import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;

public class LineNumberReaderDemo{
       public static void main(String[] args) throws IOException {
            FileReader fr = new FileReader("LineNumberReaderDemo.java" );
            LineNumberReader lnr = new LineNumberReader(fr);
      
            String line = null;
            
            lnr.setLineNumber(100);

             while((line = lnr.readLine()) != null){
                  System.out.println(lnr.getLineNumber() + ":" + line);
            }

            lnr.close();
      }
}



四、 IO流常用基类-字节流

读取一个键盘录入的数据,并打印在控制台上。
键盘本身就是一个标准的输入设备。对于java而言,对于这种输入设备都有对应的对象。

import java.io.IOException;
import java.io.InputStream;

public class ReadKey{
       public static void main(String[] args) throws IOException {
            readKey();
       }

       public static void readKey() throws IOException {
            InputStream in = System.in;

            int ch = in.read();//阻塞式方法
            System.out.println(ch);

            ch = in.read(); //阻塞式方法
            System.out.println(ch);

            ch = in.read(); //阻塞式方法
            System.out.println(ch);
            
            in.close();
      }
}



重点记忆:

1、获取键盘录入数据,然后将数据流向显示器,那么显示器就是目的地。通过System类的setIn,setOut方法

可以对默认设备进行改变。
    System.setIn(new FileInputStream(“1.txt”));//将源改成文件1.txt
    System.setOut(new PrintStream(“2.txt”));//将目的改成文件2.txt

    因为是字节流处理的是文本数据,可以转换成字符流,操作更方便。
    BfferedReader bufr =
               new BufferedReader(new InputStreamReader(System.in));
    BufferedWriter bufw =
                new BufferedWriter(new OutputStreamWriter(System.out));


    2、默认的输入和输出系统不需要关,它会随着系统的结束而消失。


五、流的操作规律

    之所以要弄清楚这个规律,是因为流对象太多,开发时不知道用哪个对象合适。
    想要知道对象的开发时用到哪些对象,只要通过四个明确即可。
    1、明确源和目的
         源:InputStream Reader
         目的:OutputStream Writer
    2、明确数据是否是纯文本数据
         源:是纯文本:Reader
                否:InputStream
         目的:是纯文本:Writer
                否:OutputStream 
         到这里,就可以明确需求中具体要使用哪个体系。

    3、明确具体的设备
         源设备:
         硬盘:File
         键盘:System.in
         内存:数组
         网络:Socket流
         目的设备:
         硬盘:File
         控制台:System.out
         内存:数组
         网络:Socket流
    4、是否需要其他额外功能
         是否需要高效(缓冲区):
         是,就加上buffer






0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:25757次
    • 积分:337
    • 等级:
    • 排名:千里之外
    • 原创:17篇
    • 转载:0篇
    • 译文:0篇
    • 评论:4条
    文章分类
    最新评论