Detailed explanation of java IO stream

2016.08.22-2016.08.24

 

Class content: IO stream

 

Please don't talk to me, be careful that I will post pictures if I disagree. Well, if as a beginner, I believe that you see the picture below, the whole person is not good.

 

 As soon as I saw this picture, the baby was frightened, and the whole person was not well in an instant.

Please read it 3 times by yourself, thank you!

Next, we will describe the byte stream and character stream separately.

 

One: byte stream

 

1. IO stream system: read and write data, so the IO stream is either read or write.

2. IO stream related classes: all under the java.io package.

   All related io operations will generate IOException.

3.IO: The reference is the program

   i:input. Come in, read data into the program.

   o:output: go out, write data out of the program.

put another picture




 
 

4: Classification of io streams, related classes will have corresponding words.

         4.1: From the flow of data points. Personally understand that it is the data exchange between the memory and the hard disk, the data on the memory is temporary, and the data on the hard disk is permanent.

                   Input (input): read data, data flow to the program. In other words: put the data on the hard disk into the memory

                   Output (output): write out data, write data out of the program. In other words: put the data in the memory on the hard disk

         4.2: Byte streams and character streams

                   Stream: byte stream, all data can be operated with byte stream. What the computer can really recognize is 010101, 8 0s or 1s are combined into bits, and 8 bits are a byte.

                   Reader or Writer: character stream. The character stream is an encoding mechanism added to the byte stream. It can only operate on text, although it is text, it is more appropriate to say text files, and does not include .doc and other rich text files, because these files can contain pictures or other non-text content. Can not operate on pictures or audio files.

         InputSteam: Read byte stream. OutputStream: Output byte stream.

         Reader: Read character stream, Writer: Write character stream.

5: File byte stream

         OutputStream,:抽象类  

                            文件输出字节流:FileOutputStream:节点流,跟目标设备相关联。

    实例一:

 import java.io.FileOutputStream;
 import java.io.IOException;
 
 public class FileOutputStreamDemo1 {
      
     public static void main(String[] args) throws IOException {
        //1.创建文件输出流对象,参数为全路径名
         FileOutputStream fos = new FileOutputStream("e:\\aa.txt");
         //2.写出数据
         //2.1准备数据
         String str = "要写出的数据";
         //2.2将数据转为字节数组的形式
         byte[] b = str.getBytes();
         //3.0将数据按照一个个字节地写出目标文件中
         /*for(int i=0; i<b.length; i++){
             fos.write(b[i]);
         }*/
         //3.1以下是将整个数组输出去,和3.0可到达相同的效果
         fos.write(b);
         //4.释放资源
        fos.close();
     }
 
 }

 BufferedInputStream:处理流,必须先有节点流。为了增加效率。处理的方式是将节点流包装起来

public static void testBufferedOutputStream() throws IOException{
         //在使用带缓冲区的字节流的时候先要有一个节点流作为参数,或者说先指定一个目标文件
         FileOutputStream fos = new FileOutputStream("d:\\test.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
         
         //将以下文字写到目标文件中去
         String str = "这几个文字即将通过带缓冲区的字节流写到一个文本文件中";
         bos.write(str.getBytes());
         //写完之后记得要刷新才能真正写入到文件中,不然还会保存在缓冲区里,直到释放资源
         bos.flush();
         //释放资源(关闭流)
         bos.close();
         
     }

 InputStream:抽象类。

                            文件输入字节流:FileInputStream:节点流,和要读取那个文件关联起来

import java.io.FileInputStream;
import java.io.IOException;
 
 public class FileInputStreamDemo1 {
     public static void main(String[] args) throws IOException {
         //1.创建字节输入流对象
        FileInputStream fis = new FileInputStream("e:\\bb.txt");
        //2.开始读取数据
 //        System.out.println((char)fis.read());
         int b;
         while((b=fis.read())!=-1){
             System.out.print((char)b);
         }
         fis.close();
     }
 }

  BufferedOutputStream:带缓冲区的。也是为了增加效率,处理的方式是将节点流包装起来

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/*
 * 将一个文件的文字输出到控制台
 */
public class BufferedInputStreamDemo1 {
    
    public static void main(String[] args) {
        
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        try {
            fis = new FileInputStream("d:\\aa.txt");
            bis = new BufferedInputStream(fis);
            //byte数组用来装读取到的数据
            byte[] b = new byte[1024];
            int len = -1;
            while((len = bis.read(b))!=-1){
                System.out.println(new String(b, 0, len));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
    }

}

 

6:字节流:在文件系统中,任何文件都是以二进制形式存储的,二进制用位体现(8位为一个二进制单元),8位=1字节,所以字节流可以处理任何文件。

         6.1字节流常用的一些类:

                   6.1.1输入流read(), 读到末尾返回-1

常用read(byte[] b, int off, int len) 从此输入流中将最多 len 个字节的数据读入一个 byte 数组中。

                            FileInputStream:文件输入流

                            BufferedInputStream:带缓冲区的输入流,先要传入一个节点流(输入流)作为参数

                   6.1.2输出流write()

常用write(byte[] b, int off, int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。

                            FileOutputStream:文件输入流

                            BufferedOutputStream:带缓冲区的输入流,先要传入一个节点流(输入流)作为参数

  结合输入输出流写一个文件复制的工具

public static boolean copyFile( String filePath,String target){
    
        boolean flag = false;
        //输出流,将数据写入到目标文件中
        FileOutputStream fos = null;
        //输入流,将要用的文本拿到程序中
        FileInputStream fis = null;
        //读取文本
        byte[] b = new byte[1024];
        //每次读取字符数据的有效长度
        int length = -1;
        
        try {
            fis = new FileInputStream(filePath);
            fos = new FileOutputStream(target);
            /*
             * fis.read(b):从fis关联的文件中每次读取 1024 个字节,
             * 并把读取到的字节数据保存这个数组里面,
             * 但是这个文件并不是只有1024 这个么大,有可能要读多次,所以要用循环
             * 寻到的条件是读到文件没有得读了,就是读到最后了就不读了,
             * 读到末尾的返回值是-1,如果返回值是-1则停止循环
             * 
             */
            while((length=fis.read(b)) != -1){//读到文件末尾就返回-1,不在往下读取
                //将读到的数据写入目标文件中
                fos.write(b, 0, length);
                fos.flush();//将数据刷到目标文件
            }
            System.out.println("文件复制成功!");
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        }finally{
            //关闭释放资源
            try {
                fos.close();
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        flag = true;
        return flag;
    }

 

二.字符流

 

1.字符流:在字节流的基础上添加了编码机制。很大程度上和字节流操作一样的,字符流只能操作文本类文件,准确的说应该是纯文本类文件。例如.txt,.java,.cpp,.html等

                   编码:每一个国家都有自己的编码,编码不一致往往导致的结果就是!!乱码!!。中国编码的编码:gbk

                            gbk:英文字母:1个字节,中文:2个字节,系统的默认编码。

                            unicode:统一编码。中文还是英文字母都是占2个字节。

                            utf-8: 国际编码。英文占1个字节,中文占3个字节。

                            文件是用什么编码来写的,那么就用什么编码来读取。最常用的编码是gbk和utf-8.一般的情况下,都设置为utf-8.(还有其他的很多编码:例如GB2312,big5等等)。如果想测试是否像上面所说那么多个字节的话,建议使用Notepad2文本软件,体积小功能强!(似乎再买广告了。。。)

                   Reader:读取数据

                            FileReader:文件读取字符流

                            BufferedReader://带缓冲区的字符输入流

                                     readLine() ;读取一行数据

                                     LineNumberReader;带行号.通过getLineNumber()方法获取行号

 

带行号功能的字符输入流

 

 import java.io.FileReader;
 import java.io.IOException;
 import java.io.LineNumberReader;
 
 /*LineNumberReader是BufferedReader的子类,
  * 比BufferedReader多了设置行号和获取行号的功能。
  * 使用LineNumberReader流读取文本文件,并打印在控制台上。
  * 在每行的前面添加行号。
  */

 public class LineNumberReaderDemo1 {
     public static void main(String[] args) throws IOException {
         String str = null;
           while((str = lnr.readLine()) != null){
//            lnr.setLineNumber(90);//设置行号
             System.out.print(lnr.getLineNumber()+" : ");
            System.out.println(str);
        }
        lnr.clo

 

Writer:写入数据

                            FileWrite:写入数据,记得刷新。

                            BufferedWriter://带缓冲区的字符输出流

                                     newLine():写入换行字符。

 

                                     write(String str):写入字符串。

 

/*
     * 2:用字符流复制文本文件。
     */
    public static boolean copyText(String textPath, String targetPath){
        boolean flag = false;
        if(textPath==null || textPath.trim().equals("")){
            return flag;
        }
        if(targetPath == null || targetPath.trim().equals("")){
            int end = textPath.lastIndexOf(".");
            String endStr = textPath.substring(end);//后缀名
            int index = textPath.lastIndexOf("\\");
            if(index == 0){
                index = textPath.lastIndexOf("/");
            }
            targetPath = textPath.substring(0,end)+"2"+endStr;//新文件名
        }
        
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            //字符输入流
            FileReader fr = new FileReader(textPath);
            br = new BufferedReader(fr);
            //字符输出流
            FileWriter fw = new FileWriter(targetPath);
            bw = new BufferedWriter(fw);
            
            String str = "";
            while((str=br.readLine()) != null){
                bw.write(str);
                bw.newLine();
                bw.flush();
            }
            flag = true;
        } catch (FileNotFoundException e) {
            e.printStackTrace ();
        } catch (IOException e) {
            e.printStackTrace ();
        }finally{
            try{
                bw.close();
                br.close();
            }catch (IOException e){
                e.printStackTrace ();
            }
        }
        return flag;
    }
  Convert stream: stream with encoding format

 

                            InputStreamReader; convert bytes to character stream

Transform flow example

public class SystemReadDemo1 {
    
    public static void main(String[] args) throws IOException {
        //get keyboard input
        InputStream is = System.in;
        //Convert byte stream to character stream, use InputStreamReader(InputStream in)---convert stream
        InputStreamReader isr = new InputStreamReader(is,"utf-8");
        // Convert the character stream to a character stream with a buffer
        BufferedReader br = new BufferedReader(isr);
        
        String str = null;
        while(true){
            str = br.readLine();
            if("886".equals(str)){
                break;
            }
            System.out.println(str);
        }
        br.close();
    }

}

OutputStreamWriter ;字符流转换为字节流。

转换流示例二

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;

/*
 * 1:获取键盘录入的数据,将数据写到文件中,但是以utf-8编码的形式写到文件中去。
 */
public class HomeWork1 {
    
    public static void main(String[] args) {
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            br = new BufferedReader(new InputStreamReader(System.in));
            bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("e:\\aa.txt"), "utf-8"));
            
            String str = "";
            while(true){
                str = br.readLine();
                if("exit".equals(str)){
                    //可以尝试不同的编码
                    OutputStreamWriter osw = new OutputStreamWriter(System.out, "GBK");
                    BufferedWriter bw2 = new BufferedWriter(osw);
                    bw2.write("输入结束!");
                    bw2.flush();
                    break;
                }
                bw.write(str);
                bw.newLine();
                bw.flush();
            }
            
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
这一段代码的作用是:因为BufferedInputStream为别的输入流添加缓冲功能,在创建BufferedInputStream时会创建一个内部缓冲数组,
用于缓冲数据,提高性能。默认的缓冲大小是8192KB,如果你要读取的文件大于这个默认的大小时,缓冲区没有读满是不会被写入文件的。
所以要关闭输入流,释放这个流的资源。或者用flush()这个命令强制写入。
 
            try {
                bw.close();
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

 

 

三.练习

 

1.使用字节流读取500MB~1G的文件,然后再使用缓冲流读取500MB~1G的文件,测试两者的区别

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327038787&siteId=291194637