day02_IO流

IO流体系

在这里插入图片描述

读入的操作(核心)

            //3.读入的操作
            //read(char[] cbuf):返回每次读入cbuf数组中的字符的个数。如果达到文件末尾,返回-1
            char[] cbuf = new char[5];
            int len;
            while((len = fr.read(cbuf)) != -1){
    
    
                //方式一:
                //错误的写法
//                for(int i = 0;i < cbuf.length;i++){
    
    
//                    System.out.print(cbuf[i]);
//                }
                //正确的写法
//                for(int i = 0;i < len;i++){
    
    
//                    System.out.print(cbuf[i]);
//                }
//========================================================================================
                //方式二:
                //错误的写法,对应着方式一的错误的写法
//                String str = new String(cbuf);
//                System.out.print(str);
                //正确的写法
                String str = new String(cbuf,0,len);
                System.out.print(str);
            }

节点流(文件流)FileInputOutputStreamTest和FileReaderWriterTest

从内存中写出数据到硬盘的文件里

    从内存中写出数据到硬盘的文件里。

    说明:
    1. 输出操作,对应的File可以不存在的。并不会报异常
    2.
         File对应的硬盘中的文件如果不存在,在输出的过程中,会自动创建此文件。
         File对应的硬盘中的文件如果存在:
                如果流使用的构造器是:FileWriter(file,false) / FileWriter(file):对原有文件的覆盖
                如果流使用的构造器是:FileWriter(file,true):不会对原有文件覆盖,而是在原有文件基础上追加内容

使用FileReader和FileWriter实现文本文件的复制

    public void testFileReaderFileWriter() {
    
    
        FileReader fr = null;
        FileWriter fw = null;
        try {
    
    
            //1.创建File类的对象,指明读入和写出的文件
            File srcFile = new File("hello.txt");
            File destFile = new File("hello2.txt");

            //不能使用字符流来处理图片等字节数据			[视频591]
//            File srcFile = new File("爱情与友情.jpg");
//            File destFile = new File("爱情与友情1.jpg");


            //2.创建输入流和输出流的对象
            fr = new FileReader(srcFile);
            fw = new FileWriter(destFile);


            //3.数据的读入和写出操作
            char[] cbuf = new char[5];
            int len;//记录每次读入到cbuf数组中的字符的个数
            while((len = fr.read(cbuf)) != -1){
    
    
                //每次写出len个字符
                fw.write(cbuf,0,len);

            }
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            //4.关闭流资源
            //方式一:
//            try {
    
    
//                if(fw != null)
//                    fw.close();
//            } catch (IOException e) {
    
    
//                e.printStackTrace();
//            }finally{
    
    
//                try {
    
    
//                    if(fr != null)
//                        fr.close();
//                } catch (IOException e) {
    
    
//                    e.printStackTrace();
//                }
//            }
            //方式二:
            try {
    
    
                if(fw != null)
                    fw.close();
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }

            try {
    
    
                if(fr != null)
                    fr.close();
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }

        }

    }

使用字节流FileInputStream处理文本文件,可能出现乱码(视频592)

    //使用字节流FileInputStream处理文本文件,可能出现乱码。
    @Test
    public void testFileInputStream() {
    
    
        FileInputStream fis = null;
        try {
    
    
            //1. 造文件
            File file = new File("hello.txt");

            //2.造流
            fis = new FileInputStream(file);

            //3.读数据
            byte[] buffer = new byte[16];  //最小为8时才不出现乱码
            int len;//记录每次读取的字节的个数
            while((len = fis.read(buffer)) != -1){
    
    

                String str = new String(buffer,0,len);
                System.out.print(str);

            }
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if(fis != null){
    
    
                //4.关闭资源
                try {
    
    
                    fis.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }

            }
        }

    }
结论:

1. 对于文本文件(.txt,.java,.c,.cpp),使用字符流处理
2. 对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt,...),使用字节流处理

开发中不会使用文件流,一般使用缓冲流。

在这里插入图片描述

处理流之一:缓冲流的使用:BufferedTest1

自己的规范实现(缓冲流实现非文本文件的复制)(视频595)

package com.atguigu.test_1;

import java.io.*;

public class BufferedTest_1 {
    
    
    public static void main(String[] args) throws IOException {
    
    
        //造文件
        File srcFile = new File("壁纸.png");
        File destFile = new File("复制的壁纸.png");
        //造流
        //造节点流
        FileInputStream fis = new FileInputStream(srcFile);
        FileOutputStream fos = new FileOutputStream(destFile);

        //造缓冲流
        BufferedInputStream bis = new BufferedInputStream(fis);
        BufferedOutputStream bos = new BufferedOutputStream(fos);

        //复制的细节:读取、写入
        byte[] bytes = new byte[5];
        int len;

        //13467:用fis和fos
        //88:用bis和bos
        long start = System.currentTimeMillis();
        while ((len = bis.read(bytes)) != -1) {
    
    
            bos.write(bytes, 0, len);
        }
        long end = System.currentTimeMillis();
        System.out.println(end - start);

        //资源的关闭:关闭缓冲流即可
        bis.close();
        bos.close();
    }
}

缓冲流(字符型)实现文本文件的复制(视频597)
使用BufferedReader和BufferedWriter实现文本文件的复制

不加try-catch-finally时更方便看(直接抛出异常)

    //去掉处理异常
    @Test
    public void testBufferedReaderBufferedWriter1() throws IOException {
    
    
        //创建文件和相应的流
        BufferedReader br = new BufferedReader(new FileReader(new File("dbcp.txt")));
        BufferedWriter bw = new BufferedWriter(new FileWriter(new File("dbcp1.txt")));

        //读写操作
        //方式一:使用char[]数组
//            char[] cbuf = new char[1024];
//            int len;
//            while((len = br.read(cbuf)) != -1){
    
    
//                bw.write(cbuf,0,len);
//    //            bw.flush();
//            }

        //方式二:使用String
        String data;
        while ((data = br.readLine()) != null) {
    
    
            //方法一:
//                bw.write(data + "\n");//data中不包含换行符
            //方法二:
            bw.write(data);//data中不包含换行符(数据全部写到一行中)
            bw.newLine();//提供换行的操作

        }
        //关闭资源
        bw.close();
        br.close();
    }
使用try-catch-finally更加规范

    @Test
    public void testBufferedReaderBufferedWriter(){
    
    
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
    
    
            //创建文件和相应的流
            br = new BufferedReader(new FileReader(new File("dbcp.txt")));
            bw = new BufferedWriter(new FileWriter(new File("dbcp1.txt")));

            //读写操作
            //方式一:使用char[]数组
//            char[] cbuf = new char[1024];
//            int len;
//            while((len = br.read(cbuf)) != -1){
    
    
//                bw.write(cbuf,0,len);
//    //            bw.flush();
//            }

            //方式二:使用String
            String data;
            while((data = br.readLine()) != null){
    
    
                //方法一:
//                bw.write(data + "\n");//data中不包含换行符
                //方法二:
                bw.write(data);//data中不包含换行符(数据全部写到一行中)
                bw.newLine();//提供换行的操作

            }
            
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            //关闭资源
            if(bw != null){
    
    

                try {
    
    
                    bw.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
            if(br != null){
    
    
                try {
    
    
                    br.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }

            }
        }

    }

在这里插入图片描述

扫描二维码关注公众号,回复: 12550171 查看本文章

处理流之二:转换流:InputStreamReaderTest

转换流实现文件的读入和写出(视频601)
在这里插入图片描述

1.转换流:属于字符流
   InputStreamReader:将一个字节的输入流转换为字符的输入流
   OutputStreamWriter:将一个字符的输出流转换为字节的输出流

2.作用:提供字节流与字符流之间的转换

3. 解码:字节、字节数组  --->字符数组、字符串
   编码:字符数组、字符串 ---> 字节、字节数组
   
4.字符集(视频602)
 *ASCII:美国标准信息交换码。
    用一个字节的7位可以表示。
 ISO8859-1:拉丁码表。欧洲码表
    用一个字节的8位表示。
 GB2312:中国的中文编码表。最多两个字节编码所有字符
 GBK:中国的中文编码表升级,融合了更多的中文文字符号。最多两个字节编码
 Unicode:国际标准码,融合了目前人类使用的所有字符。为每个字符分配唯一的字符码。所有的文字都用两个字节来表示。
 UTF-8:变长的编码方式,可用1-4个字节来表示一个字符。


InputStreamReader的使用,实现字节的输入流到字符的输入流的转换(视频600)

    @Test
    public void test1() throws IOException {
    
    

        FileInputStream fis = new FileInputStream("dbcp.txt");
//        InputStreamReader isr = new InputStreamReader(fis);//使用系统默认的字符集
        //参数2指明了字符集,具体使用哪个字符集,取决于文件dbcp.txt保存时使用的字符集
        InputStreamReader isr = new InputStreamReader(fis,"UTF-8");//使用系统默认的字符集

        char[] cbuf = new char[20];
        int len;
        while((len = isr.read(cbuf)) != -1){
    
    
            String str = new String(cbuf,0,len);
            System.out.print(str);
        }

        isr.close();

    }
综合使用InputStreamReader和OutputStreamWriter

    @Test
    public void test2() throws Exception {
    
    
        //1.造文件、造流
        File file1 = new File("dbcp.txt");
        File file2 = new File("dbcp_gbk.txt");
        
        //字节流
        FileInputStream fis = new FileInputStream(file1);
        FileOutputStream fos = new FileOutputStream(file2);
        //转换流
        InputStreamReader isr = new InputStreamReader(fis,"utf-8");
        OutputStreamWriter osw = new OutputStreamWriter(fos,"gbk");

        //2.读写过程
        char[] cbuf = new char[20];
        int len;
        while((len = isr.read(cbuf)) != -1){
    
    
            osw.write(cbuf,0,len);
        }

        //3.关闭资源
        isr.close();
        osw.close();


    }

字符编码

字符集:

ASCII:美国标准信息交换码。用一个字节的7位可以表示。

ISO8859-1:拉丁码表。欧洲码表用一个字节的8位表示。

 GB2312:中国的中文编码表。最多两个字节编码所有字符
 GBK:中国的中文编码表升级,融合了更多的中文文字符号。最多两个字节编码

 Unicode:国际标准码,融合了目前人类使用的所有字符。为每个字符分配唯一的字符码。所有的文字都用两个字节来表示。
 UTF-8:变长的编码方式,可用1-4个字节来表示一个字符。

在这里插入图片描述

在这里插入图片描述

其他流的使用:OtherStreamTest

    3. 数据流(保存内存中的变量的时候使用)(视频605)

    3.1 DataInputStream 和 DataOutputStream
    3.2 作用:用于读取或写出基本数据类型的变量或字符串

    练习:将内存中的字符串、基本数据类型的变量写出到文件中。

    注意:处理异常的话,仍然应该使用try-catch-finally.
先写

    @Test
    public void test3() throws IOException {
    
    
        //1.处理流包着节点流
        DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
        //2.
        dos.writeUTF("张三");
        dos.flush();//刷新操作,将内存中的数据写入文件

        dos.writeLong(98);
        //dos.flush();
        dos.writeInt(99);
        //dos.flush();
        dos.writeBoolean(true);
        //dos.flush();
        //3.
        dos.close();
    }

再读
    @Test
    public void test4() throws IOException {
    
    
        //1.
        DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
        //2.读
        String name = dis.readUTF();
        int age = dis.readInt();
        boolean isMale = dis.readBoolean();

        System.out.println("name = " + name);
        System.out.println("age = " + age);
        System.out.println("isMale = " + isMale);

        //3.
        dis.close();
    }
    2. 打印流:PrintStream 和PrintWriter(只有输出)(视频604)

    2.1 提供了一系列重载的print() 和 println()
    自动刷新功能autoFlush为true
    前提条件:使用println、printf、format方法
    @Test
    public void test2() {
    
    
        PrintStream ps = null;
        try {
    
    
            FileOutputStream fos = new FileOutputStream(new File("D:\\IO\\text.txt"));

            // 创建打印输出流,设置为自动刷新模式(写入换行符或字节 '\n' 时都会刷新输出缓冲区)
            ps = new PrintStream(fos, true);
            if (ps != null) {
    
    
                System.setOut(ps);// 把标准输出流(控制台输出)改成文件
            }


            for (int i = 0; i <= 255; i++) {
    
     // 输出ASCII字符
                System.out.print((char) i);
                if (i % 50 == 0) {
    
     // 每50个数据一行
                    System.out.println(); // 换行
                }
            }


        } catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if (ps != null) {
    
    
                ps.close();
            }
        }

    }
    1.标准的输入、输出流(视频603)
    
    1.1
    System.in:标准的输入流,默认从键盘输入
    System.out:标准的输出流,默认从控制台输出
    1.2
    System类的setIn(InputStream is) / setOut(PrintStream ps)方式重新指定输入和输出的流。

    (重要)1.3练习:
    从键盘输入字符串,要求将读取到的整行字符串转成大写输出。然后继续进行输入操作,
    直至当输入“e”或者“exit”时,退出程序。

    方法一:使用Scanner实现,调用next()返回一个字符串
    方法二:使用System.in实现。System.in(字节流)  --->  转换流 ---> BufferedReader的readLine()(字符流)
    //(自己:去掉异常处理)
    public static void test() throws IOException{
    
    

        InputStreamReader isr = new InputStreamReader(System.in);   //System.in为键盘输入
        BufferedReader br = new BufferedReader(isr);

        while (true) {
    
    
            System.out.println("请输入字符串:");
            String data = br.readLine();
            //进行判断
            if ("e".equalsIgnoreCase(data) || "exit".equalsIgnoreCase(data)) {
    
    
                System.out.println("程序结束");
                break;
            }
            String upperCase = data.toUpperCase();
            System.out.println(upperCase);
        }
        br.close();
    }
序列化流与反序列化流
ObjectInputStream

有选择的序列化:成员变量用transisent关键字修饰
transisent int age;

例如,要从由 ObjectOutputStream 中的示例写入的流读取:


        FileInputStream fis = new FileInputStream("t.tmp");
        ObjectInputStream ois = new ObjectInputStream(fis);

        int i = ois.readInt();
        String today = (String) ois.readObject();
        Date date = (Date) ois.readObject();

        ois.close();

猜你喜欢

转载自blog.csdn.net/AC_872767407/article/details/113872481