java IO流

IO

字符集:

常见字符集:ASCll 包括了数字,英文,符号。

ASCll使用一个字节存储字符,一个字节是八位,总共可以表示128个字符

GBK:用来存储中文字符,window系统默认的字符

Unicode码表:统一全球的编码,万国码。UTF-8,UTF-16…。技术UTF_8人员都应该使用UTF_8,编码前和解码后必须要一致,不然会乱码。

字符的编码有多种方案,一个英文字符在ASCII码、Unicode码、UTF-8编码中,分别占用一个、两个、一个字节的空间;一个汉字字符在ASCII码、Unicode码、UTF-8编码中,分别占用两个、两个、三个字节的空间

结论:计算机底层可以表示十进制编号。计算机可以给人类符号进行编号存储,即字符集

IO流概述:

按方向分类:分为输入流,输出流

输入流:是数据从硬盘文件,读入到内存的过程

输出流:是内存程序的数据从内存写出到硬盘文件的过程,称之为输出,负责写。

按流中的数据最小单位分为:字节流,字符流。

  • 字节输入流:以内存为基准,来自磁盘中的文件/网络中的数据以字节的形式读入到内存中,称为字节输入流

  • 字节输出流:以内存为基准,来自内存的数据以字节的形式读入到磁盘中的文件/网络中,称为字节输出流

    • InputStream,OutputStream
  • 字符输入流:以内存为基准,来自磁盘中的文件/网络中的数据以字符的形式读入到内存中,称为字符输入流

  • 字符输出流:以内存为基准,来自内存的数据以字符的形式读入到磁盘中的文件/网络中,称为字符输出流

    • Reader , Writer
//文件字节输入流,api
public int read();
//每次读取一个字节返回,如果没有字节返回-1;

读取一个字节存在什么问题:

  • 性能较慢
  • 读取中文字符,容易出现乱码问题。

文件字节输入流:FileInputStream

文件字节输出流:FileOutputStream

//以字节的形式将数据读取到内存中去
public int read();
public int read(byte[] buffer);

控制台=内存,磁盘,网络文件

外:磁盘,网络文件

内:内存,控制台

字节流读取:

常用API:

write();

read();

根据参数不同选择不同

int,char[],String,off,set如下代码:

package com.pan.Stream;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

public class FileStream {
    public static void main(String[] args) throws Exception {
        File f= new File("FileTest/src/test.txt");
        InputStream is = new FileInputStream(f);
       /* int b1 = is.read();
        System.out.println(b1);

        int b4 = is.read();
        System.out.println(b4);
        int b3 = is.read();
        System.out.println(b3);
        int b2 = is.read();
        System.out.println(b2);
        */
       //依然无法避免乱码,会把中文截断,一个中文字符栈用三个字节,一个英文字符占一个字节
        /*byte[] bytes = new byte[3];
        int len;
        while((len = is.read(bytes)) != -1){
            System.out.println(new String(bytes,0,len));
        }*/


        /*System.out.println("读取了几个字节"+len);
        String rs = new String(bytes,1,2);
        System.out.println(rs);*/

        //将文件所有的字符一次性接收
       /* byte[] buffer = new byte[(int) f.length()];
        int len = is.read(buffer);
        System.out.println("长度为:"+len);
        System.out.println("长度为:"+f.length());
        System.out.println(new String(buffer));*/

      // byte[] buffer = is.readALLBByte();
    }
}

字符流读取:

package com.pan.Stream;

/*
*由于字节流读取文件会出现乱码
* 使用字符流读取和写入,最小单位是按照字符开始的
* Reader(抽象)--->FileReader(实现类)
* */

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.Reader;

public class FileInputStringStream {

    public static void main(String[] args) throws Exception {
        //目标:每次读取一个字符
        //1。创建一个字符输入流管道与原文件接通
        Reader reader = new FileReader("FileTest/src/dataCode.txt");
        //2.读取一个字符
        int count = reader.read();
        System.out.println((char)count);

        int code ;
        while((code = reader.read()) != -1){
            System.out.print((char)code);
        }
        //不能重复读,上面的循环完后,下面的循环输出为空;必须注释掉上面
        char[] characters = new char[1024];
       // int count1 = reader.read(characters,0,3);
        //记录读取字符的个数
        int len;
        System.out.println("=========================================================================");
        while((len = reader.read(characters)) != -1){
            String rs = new String(characters,0,len);
            System.out.print(rs);
        }
        //System.out.println((char)count1);
    }

}

输出流

package com.pan.Stream;

/*
* 写入外部文件,以字符为基础
* 写到磁盘文件
* Writer(抽象类)---->FileWriter(实现类)
* */

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

public class FileOutStringStream {

    //1.创建一个文件输出流
    public static void main(String[] args) throws IOException {
        Writer writer = new FileWriter("FileTest/src/data字符.txt",true);
        //2.常用API
        writer.write(99);
        writer.write("年后就");
        writer.write('a');
        //换行
        writer.write("\r\n");
        char[] chars = "我似乎好像是输出流".toCharArray();
        writer.write(chars);
        writer.write("\r\n");
        writer.write("我是中国人",0,2);
        //刷新
        writer.flush();//刷新后,流可以继续使用
        //关闭流
        writer.close();//关闭包含刷新,关闭后流不可以使用
    }

}

字节 缓冲流

package com.pan.StreamAreasBuffer;

import java.io.*;
/*
* Buffer高级流,性能更好
* */

public class ByteBufferDemo {

    public static void main(String[] args) {

//            InputStream inputStream = null;
//            OutputStream outputStream = null;
            //创建一个字节输入流管道与视屏文件接通
            try(
                    //try()中会自动关闭流。
                    InputStream inputStream = new FileInputStream("E:\\图库\\OIP-C.jpg");
                    //2.创建一个字节输出流管道与目标文件接通
                    //把原始的字节输入流包装成高级的缓冲输入流
                    InputStream bis = new BufferedInputStream(inputStream);
                    //文件的速度慢于内存,outputStream 不在内存中非常慢
                    OutputStream outputStream = new FileOutputStream("FileTest/src/image01.png");
                    //把字节输出流包装在高级的缓冲字节输出流管道,8kb的缓冲池,存储空间小,查找快,读取快
                    OutputStream outputStream1 = new BufferedOutputStream(outputStream);
            ) {

                byte[] buffer = new byte[1024];
                int len ;
                while((len = bis.read(buffer) ) != -1){
                    outputStream1.write(buffer,0,len);
                }
                System.out.println("赋值完成了");
            } catch (IOException e) {
                e.printStackTrace();
            }
            finally {
                System.out.println("=====================finally=================");
            }
        }

    }

文件复制案例与性能对比

package com.pan.StreamAreasBuffer;

import java.io.*;
import java.nio.Buffer;
import java.util.Collections;

public class CompareTimeBuffer {

    public static void main(String[] args) {
        copyBufferStreamTime();
        copyOldStreamTime();
        copyBufferStreamTimeBit();
        copyOldStreamTimeBit();
    }

    public static void copyOldStreamTime(){
        long startTime = System.currentTimeMillis();
//            InputStream inputStream = null;
//            OutputStream outputStream = null;
            //创建一个字节输入流管道与视屏文件接通
            try(
                    InputStream inputStream = new FileInputStream("E:\\图库\\2019年下半年软件设计师下午真题及答案解析.word");
                    //2.创建一个字节输出流管道与目标文件接通
                    OutputStream outputStream = new FileOutputStream("FileTest/src/papers01.pdf");
            ) {

                byte[] buffer = new byte[1024];
                int len ;
                while((len = inputStream.read(buffer) ) != -1){
                    outputStream.write(buffer,0,len);
                }
                System.out.println("赋值完成了");
            } catch (IOException e) {
                e.printStackTrace();
            }
            finally {
                System.out.println("=====================finally=================");
            }
            long endTime = System.currentTimeMillis();
            System.out.println("使用--原始的--字节流(一个数组)的形式复制文件"+(endTime - startTime)/1000.0 + "s");
    }

    public static void copyBufferStreamTime(){
        long startTime = System.currentTimeMillis();
//            InputStream inputStream = null;
//            OutputStream outputStream = null;
        //创建一个字节输入流管道与视屏文件接通
        try(
                InputStream inputStream = new FileInputStream("E:\\图库\\2019年下半年软件设计师下午真题及答案解析.word");
                InputStream inputStream1 = new BufferedInputStream(inputStream);
                //2.创建一个字节输出流管道与目标文件接通
                OutputStream outputStream = new FileOutputStream("FileTest/src/papers02.pdf");
                OutputStream outputStream1 = new BufferedOutputStream(outputStream);
        ) {

            byte[] buffer = new byte[1024];
            int len ;
            while((len = inputStream1.read(buffer) ) != -1){
                outputStream1.write(buffer,0,len);
            }
            System.out.println("赋值完成了");
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            System.out.println("=====================finally=================");
        }
        long endTime = System.currentTimeMillis();
        System.out.println("使用--缓冲--字节流(一个数组)形式复制文件"+(endTime - startTime)/1000.0 + "s");
    }

    public static void copyOldStreamTimeBit(){
        long startTime = System.currentTimeMillis();
//            InputStream inputStream = null;
//            OutputStream outputStream = null;
        //创建一个字节输入流管道与视屏文件接通
        try(
                InputStream inputStream = new FileInputStream("E:\\图库\\2019年下半年软件设计师下午真题及答案解析.word");
                //2.创建一个字节输出流管道与目标文件接通
                OutputStream outputStream = new FileOutputStream("FileTest/src/papers03.pdf");
        ) {
           //一个一个字节输出
            int len ;
            while((len = inputStream.read() ) != -1){
                outputStream.write(len);
            }
            System.out.println("赋值完成了");
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            System.out.println("=====================finally=================");
        }
        long endTime = System.currentTimeMillis();
        System.out.println("使用--原始的--字节流(一个一个字节)的形式复制文件"+(endTime - startTime)/1000.0 + "s");
    }

    public static void copyBufferStreamTimeBit(){
        long startTime = System.currentTimeMillis();
//            InputStream inputStream = null;
//            OutputStream outputStream = null;
        //创建一个字节输入流管道与视屏文件接通
        try(
                InputStream inputStream = new FileInputStream("E:\\图库\\2019年下半年软件设计师下午真题及答案解析.word");
                InputStream inputStream1 = new BufferedInputStream(inputStream);
                //2.创建一个字节输出流管道与目标文件接通
                OutputStream outputStream = new FileOutputStream("FileTest/src/papers04.pdf");
                OutputStream outputStream1 = new BufferedOutputStream(outputStream);
        ) {

            int len ;
            while((len = inputStream1.read() ) != -1){
                outputStream1.write(len);
            }
            System.out.println("赋值完成了");
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            System.out.println("=====================finally=================");
        }
        long endTime = System.currentTimeMillis();
        System.out.println("使用--缓冲--字节流(一个一个字节)的形式复制文件"+(endTime - startTime)/1000.0 + "s");
    }


}

结果如下:

赋值完成了
=====finally=
使用–缓冲–字节流(一个数组)形式复制文件0.014s
赋值完成了
=====finally=
使用–原始的–字节流(一个数组)的形式复制文件0.026s
赋值完成了
=====finally=
使用–缓冲–字节流(一个一个字节)的形式复制文件0.046s
赋值完成了
=====finally=
使用–原始的–字节流(一个一个字节)的形式复制文件10.532s

Process finished with exit code 0

字符缓冲流

BufferedRead

package com.pan.StreamAreasBuffer;

/*
* 目标:学会使用字符缓冲输入流/输出流提高自己的性能(8k空间)
* 并学习新增的方法(readLine())优先使用
* Reader---->BufferedReader(继承)
* 经典代码:字符流,行读,不需要字符流桶,桶读会截断。
* */

import java.io.*;

public class BufferReaderDemo01 {
    public static void main(String[] args) throws Exception {
        try ( //1.创建一个Reader的字符流与原文件接通
              Reader reader = new FileReader("FileTest/src/data1.txt");
              BufferedReader bufferedReader = new BufferedReader(reader);
        ) {
            //2.用循环,将文件读取出来
//            char[] chars = new char[1024];
//            int len ;
//            while((len = reader.read(chars)) != -1){
//                String s = new String(chars,0,len);
//                System.out.println(s);
//            }
            String line;
            while((line = bufferedReader.readLine())!= null){
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

输出

package com.pan.StreamAreasBuffer;

/*
 * 目标:学会使用字符缓冲输出流/输出流提高自己的性能(8k空间)
 * 并学习新增的方法()优先使用
 * Writer---->BufferedWriter(继承)
 * */


import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

public class BufferWriterDemo01 {

    //1.创建一个文件输出流
    public static void main(String[] args) throws IOException {
        Writer fw = new FileWriter("FileTest/src/data字符.txt",true);
        BufferedWriter bufferedWriter = new BufferedWriter(fw);
        //2.常用API
        bufferedWriter.write(99);
        bufferedWriter.write("年后就========================================================");
        bufferedWriter.write('a');
        //换行
        bufferedWriter.write("\r\n");
        char[] chars = "我似乎好像是输出流".toCharArray();
        bufferedWriter.write(chars);
        bufferedWriter.write("\r\n");
        bufferedWriter.write("我是中国人",0,2);
        //刷新
        bufferedWriter.flush();//刷新后,流可以继续使用
        //关闭流
        bufferedWriter.close();//关闭包含刷新,关闭后流不可以使用
    }
java

}

案例:

乱序的出师表恢复

package com.pan.items;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/*
* 拷贝一个出师表
* */
public class TeacherForm {

    public static void main(String[] args) {
        try( //1.创建一个Buffered输入流
             Reader reader = new FileReader("FileTest/src/出师表.txt");
             BufferedReader bufferedReader = new BufferedReader(reader);) {
            //2.创建一个list数组存放行字符,list可以默认排序
            List<String> data = new ArrayList<>();
            //按行读取字符,并添加到数组里
            String Line;
            while((Line = bufferedReader.readLine()) != null){
                data.add(Line);
            }
            System.out.println(data);
            //排序
            Collections.sort(data);
            System.out.println(data);

            //自定义排序规则
            List<String> size = new ArrayList<>();
            Collections.addAll(size,"一","二","三","四","五","六","七","八","九");
            Collections.sort(data, new Comparator<String>() {
                @Override
                public int compare(String o1, String o2) {

                    return size.indexOf(o1.substring(0,o1.indexOf("\\.")))- size.indexOf(o2.substring(0,o2.indexOf("\\.")));
                }
            });
            System.out.println(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

读取乱码问题(代码与文件编码不一致)

读写编码格式设置

使用以下两个流

InputStreamReader: 有多种构造器

package com.pan.problemsolve;

/*
* 当文件编码格式与代码编码格式不一致时解决办法
* 使用 Reader ----> InputStreamReader(input,charset);
* */

import java.io.*;

public class ConfuseCode {

    public static void main(String[] args) throws Exception {
        try ( //1.创建一个Reader的字符流与原文件接通,文档编码不一致,一个是GBK 一个是UTF-8,由于对中文编码字节数数不一致的
//              Reader reader = new FileReader("E:/文档/data.txt");,这是原本的文件读取方式,会出现乱码,由于编码的不一致
//              BufferedReader bufferedReader = new BufferedReader(reader);
              InputStream inputStream = new FileInputStream("E:/文档/data01.txt");
              //BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
              //2.通过字符流的子实现类的构造方式去确定流的读取编码方式。得到流数据
              Reader reader = new InputStreamReader(inputStream,"GBK");
              //3.设置缓冲区流,将流反倒缓冲区
              BufferedReader bufferedReader = new BufferedReader(reader);
        ) {
            //当然也可以让直接字节容器读取,但要确定文件大小才行
           /* byte[] bytes = new byte[10];
            int line;

            while((line = bufferedInputStream.read(bytes))!= -1){
                String s = new String(bytes,0,line);
                System.out.println(s);*/
           //4.读取到控制台,按行读取。
           String Line;
           while((Line = bufferedReader.readLine() ) != null){
               System.out.println(Line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}

OutStreamWriter: 有多种构造器

package com.pan.problemsolve;

/*
*
* */

import java.io.*;

public class ConfuseCodeOut {
    public static void main(String[] args) {
        //1.定义一个字节输出流
        OutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream("FileTest/src/datacodetest.txt");
            //低级流,并指定编码。idea默认为UTF-8
            Writer writer = new OutputStreamWriter(outputStream,"GBK");
            //高级流
            BufferedWriter bufferedWriter = new BufferedWriter(writer);
            bufferedWriter.write("我爱你中国~~~~~~~~~");
            bufferedWriter.close();
        } catch (Exception e) {
            e.printStackTrace();
        }



    }
}

对象序列

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值