I/O流学习

话不多说,上图!


字节文件输入流读取二进制文件,转换为字符流输出到控制台:
FileInputStream与InputStreamReader的配合使用

package com.atguigu.javase.a1109;

import java.io.*;
public class BufferedReaderStu {
    public static void main(String[] args) {

        // 读取一个二进制文件,字节文件输入流读取,转换为字符文件
        FileInputStream fis = null;
        // 转换流转换为UTF8格式
        InputStreamReader isr = null;
        // Reader isr = null;
    
        // 上面两种Reader都可以,Reader是多态写法,InputStreamReader是Reader的子类

        try {
            fis = new FileInputStream("D:/iofile.txt");
            isr = new InputStreamReader(fis, "UTF8");// 参数写“UTF8"或者”JBK“
            
            // 定义一个StringBuffer作为缓冲,将每次遍历的字符串追加到遍历出来的内容中
            StringBuffer sb = new StringBuffer();
            char[] ch = new char[1024];
            int len;
            while ((len = isr.read(ch)) != -1){
                sb.append(ch);
            }
            System.out.println(sb);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fis.close();
                isr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

控制台输出:

System.out.println(System.getProperty("file.encoding"));  获得本地平台的字符编码类型

InputStreamReader后面的参数是为了可以设置编码集,设置为"UTF8"就可以避免中文乱码

因此,读取文件出现中文乱码有两种解决方案:

方式一:
        手工调整文件编码格式与程序环境编码格式一致
方式二:
        使用Reader子类InputStreamReader
        InputStreamReader(InputStream in)
        InputStreamReader(InputStream in,String charsetName)

注意!!!

文件名有可能找不到,看看你创建的文件扩展名是不是隐藏了!!!

表面上文件是存在的,但是还是报错:文件找不到

这个时候如果文件路径和文件名没错的话,那就是文件的扩展名被隐藏了!!!

点击查看下面的"文件扩展名",勾选前面的选项,这样就会看见是2个".txt",这里的坑要小心!!!


上述读取文件的方式是按照数组长度的形式读取的,如果文件过大,可以采用"按行遍历"的方式:


行遍历的方法是readLine(),这个方法只有BufferedReader这个类有。

这里解释一下BufferedReader类:字符输入缓冲流。从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

package com.atguigu.javase.a1109;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class Test {
    public static void main(String[] args) {
        // 当文件过大时,需要按行遍历,效率更高
        // 按行遍历readLine()方法只有BufferedReader有,所以先创建BufferedReader类
        // BufferedReader需要传递Reader对象作为参数,Reader的子类是InputStreamReader类(转换流)
        // 相当于在之前遍历的转换流的基础上嵌套一层缓冲流

        FileInputStream fis= null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        try {
            // 文件输入流
            fis = new FileInputStream("D:/iofile.txt");
            // 转换流
            isr = new InputStreamReader(fis,"UTF8");
            // 缓冲流
            br = new BufferedReader(isr);
            String content = "";
            while ((content = br.readLine()) != null){
                System.out.println(content);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fis.close();
                isr.close();
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

 控制台输出:


用缓冲流往设备中输出数据并解决中文乱码问题:

用到的类有:

FileOutputStream:文件输出流,是用于将数据写入File或 FileDescriptor的输出流。

OutputStreamWriter: 是从字符流到字节流的桥接,使用指定的字符集将写入其中的字符编码为字节。它使用的字符集可以通过名称指定,也可以明确指定,或者可以接受平台的默认字符集。

BufferedWriter:字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。

package com.atguigu.javase.a1109;

import java.io.*;

public class Test {
    public static void main(String[] args) {
        // 往文件中输出内容
        FileOutputStream fos = null;
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;
        try {
            // 字节文件输出流
             fos = new FileOutputStream("D:/bufwri.txt");
            // 转换流
             osw = new OutputStreamWriter(fos,"UTF8");
            // 缓冲流
             bw = new BufferedWriter(osw);

             // 输出数据
            bw.write("上海\n");
            bw.write("北京");
            bw.newLine();
            bw.write("南京");
            bw.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fos.close();
                osw.close();
                bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

---------------------------------------------------------小练习-------------------------------------------------------------

需求说明:

        读取模板文件pet.template.txt的模板格式内容(保存宠物数据),把{name}、{type}、{master}替换为具体的宠物信息,将替换后的内容重新写入到pet.txt中

替换前:您好! 我的名字是{name},我是一只{type}。 我的主人是{master}。

替换后:您好! 我的名字是欧欧,我是一只狗狗。 我的主人是李伟。

package com.atguigu.javase.a1109;

import java.io.*;

public class Test {
    public static void main(String[] args) {
        // 按行读取文件内容
        FileInputStream fis = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        try {
            // 字节文件输入流
             fis = new FileInputStream("pet.template.txt");
            // 转换流
             isr = new InputStreamReader(fis,"UTF8");
            // 缓冲流
            br = new BufferedReader(isr);

            // 读取数据,且将内容以字符串的形式输出在控制台
            StringBuffer sb = new StringBuffer();
            String content;
            while ((content = br.readLine()) != null){
                // System.out.println(content);
                sb.append(content);
            }
            // 替换内容
            String s = sb.toString();
            s=s.replace("{name}","欧欧");
            s=s.replace("{type}","狗狗");
            s=s.replace("{master}","李伟");
            // 字节文件输出流
            FileOutputStream fos = new FileOutputStream("pet.txt",true);
            // 字节文件转换流
            OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF8");
            // 缓冲流
            BufferedWriter bw = new BufferedWriter(osw);
            // 优化
            // BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("pet.txt",true), "UTF8"));
            // 输出数据
            bw.write(s);
            bw.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fis.close();
                isr.close();
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

上述代码可以优化一下:

package nj.zb.kb21.a1109;

import java.io.*;

public class Exercise {
    public static void main(String[] args) {
        // 替换文件内容
        // 按行遍历文件
        // 缓冲流
        BufferedReader br = null;
        try {
           br = new BufferedReader(new InputStreamReader(new FileInputStream("pet.template.txt"), "UTF8"));
           // 读取数据
            StringBuffer sb = new StringBuffer();
            String content;
            while ((content = br.readLine()) != null){
                sb.append(content);
            }
            String newStr = sb.toString();
            // 替换内容
            newStr = newStr.replace("{name}","欧欧");
            newStr = newStr.replace("{type}","狗狗");
            newStr = newStr.replace("{master}","李伟");
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("pet.txt", true), "UTF8"));
            bw.write(newStr);
            bw.flush();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}


读写二进制文件要用的类:成对配合使用。

FileInputStream

DataInputStream:是指数据输入流允许应用程序

FileOutputStream

DataOutputStream:是数据输出流,此类继承自FillterOutputStream类,同时实现DataOutput接口。在DataOutput接口定义了一系列写入各种数据的方法。

package com.atguigu.javase.a1109;

import java.io.*;

public class DataInputOutputStreamTest {
    public static void main(String[] args) {
        FileInputStream fis = null;
        DataInputStream dis = null;
        FileOutputStream fos = null;
        DataOutputStream ops = null;
        try {
            fis = new FileInputStream("./resources/微信截图.png");
            dis = new DataInputStream(fis);
            fos = new FileOutputStream("./resources/微信截图2.png");
            ops = new DataOutputStream(fos);

            int temp;
            while ((temp = dis.read()) != -1){
                ops.write(temp);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                ops.close();
                fos.close();
                dis.close();
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值