JavaSE-IO流

IO流

IO流用来处理设备之间的数据传输
java对数据的操作是通过流的方式
java用于操作流的对象都在IO包中
流按操作数据分为两种:字节流和字符流
按流向分为输入流和输出流

字符编码

一、ASCII: 美国(国家)信息交换标准(代)码,一种使用7个或8个二进制位进行编码的方案,最多可以给256个字符(包括字母、数字、标点符号、控制字符及其他符号)分配(或指定)数值
二、GBK-2312: 是中华人民共和国国家汉字信息交换用编码,全称《信息交换用汉字编码字符集——基本集》,1980年由国家标准总局发布。基本集共收入汉字6763个和非汉字图形字符682个,通行于中国大陆。新加坡等地也使用此编码。
三、UNICODE:如果有一种编码,将世界上所有的符号都纳入其中,无论是英文、日文、还是中文等,大家都使用这个编码表,就不会出现编码不匹配现象。每个符号对应一个唯一的编码,乱码问题就不存在了。这就是Unicode编码。Unicode所有字符都用2个字节表示。
四、UTF-8:为了提高Unicode的编码效率,于是就出现了UTF-8编码。UTF-8可以根据不同的符号自动选择编码的长短。比如英文字母可以只用1个字节就够了。

IO流常用基类

字节流的抽象基类:InputStream,OutputStream
字符流的抽象基类:Reader,Writer
由这四个类派生出来的子类名称都以其父类名作为子类名的后缀
字符流融合了字符编码表,用于处理文字类

FileWriter 往文件中写入数据

在这里插入图片描述

    public static void main(String[] args) throws IOException {
        // 创建FileWriter流对象
        // 在指定位置创建文件
        // 如果在该目录下有同名文件,将被覆盖
        FileWriter fw = new FileWriter("a.txt");
        // 添加字符串到内存中或者说流的缓冲中
        fw.write("as");
        // 将流缓冲中的数据写入文件
        fw.flush();
        // 将流缓冲中的数据写入文件
        // 关闭流对象
        fw.close();
        // 创建FileWriter流对象
        // 在指定位置创建文件
        // 如果在该目录下有同名文件,追加文件内容
        FileWriter fw2 = new FileWriter("a.txt", true);
        fw2.close();
    }

IO异常处理方式

标准写法:

public static void main(String[] args)  {
    FileWriter fw=null;
    try{
        fw = new FileWriter("a.txt");
        fw.write("as");
        fw.flush();
    }catch (IOException e){
        System.out.println(e.getMessage());
    }finally {
        try{
        	if(fw!=null){
            	fw.close();
            }
        }catch (IOException e){
            System.out.println(e.getMessage());
        }
    }
}

win的换行是\r\n,linux的换行是\n

FileReader 读取单个字符

· FileReader是InputStreamReader的子类
· FileReader的编码固定是GBK
在这里插入图片描述

    public static void main(String[] args)  {
        FileReader fr=null;
        try{
            // 创建文件读取流对象,和指定名称的文件相关联
            // 要保证文件已经存在,否则会发生FileNotFoundException异常
            fr = new FileReader("a.txt");
            while (true){
                // 读取单个字符,而且会自动往下读
                // 字符以整数返回
                int ch = fr.read();
                // -1表示读到末尾
                if(ch==-1){
                    break;
                }
                System.out.println(fr.read());
            }
//            简单写法
//            int ch = 0;
//            while((ch=fr.read()) != -1){
//                System.out.println(ch);
//            }
        }catch (IOException e){
            System.out.println(e.getMessage());
        }finally {
            try{
            	if(fr!=null){
                	fr.close();
                }
            }catch (IOException e){
                System.out.println(e.getMessage());
            }
        }
    }

FileReader 将字符读入数组

int read(char[] cbuf):发生IO错误或者已到达流的末尾前,此方法一直阻塞
参数cbuf:目标缓存区;
返回:读取的字符数;如果已到达流的末尾,则返回-1;

    public static void main(String[] args) throws IOException  {
        // 创建文件读取流对象,和指定名称的文件相关联
        // 要保证文件已经存在,否则会发生FileNotFoundException异常
        FileReader fr = new FileReader("a.txt");
        // 一般会定义1024的整数倍
        char[] buff = new char[7];
        int num = 0;
        while ((num=fr.read(buff)) != -1){
            System.out.println(new String(buff,0,num));
        }
        fr.close();
    }

拷贝文本文件

在这里插入图片描述

字符流的缓冲区

一、缓冲区用于提高数据的读写效率
二、缓冲区对应的类,BufferWriter,BufferReader
三、缓冲区要结合流才可以使用,在流的基础上对流的功能加强

BufferWriter

一、将文本写入字符输出流,缓冲各个字符,从而提高单字符、数字、字符串的高效写入。

public static void main(String[] args) throws IOException  {
    // 创建一个字符写入流对象
    FileWriter fw = new FileWriter("a.txt");
    // 添加缓冲区,缓冲区的本质是数组
    BufferedWriter bw = new BufferedWriter(fw);
    bw.write("asdfg");
    // 跨平台的换行符,
    // linux 换行是\n,win的换行是\r\n
    // newLine()支持跨平台
    bw.newLine();
    bw.flush();
    // 关闭缓冲区,就是关闭缓冲区的流对象
    bw.close();
}

BufferReader

public static void main(String[] args) throws IOException  {
    // 创建一个字符读取流对象
    FileReader fr = new FileReader("a.txt");
    // 添加缓冲区,缓冲区的本质是数组
    BufferedReader br = new BufferedReader(fr);
    // 读一行
    String line = null;
    while ((line=br.readLine())!=null){
        System.out.println(line);
    }
    // 读一个字符
    System.out.println(br.read());
    // 关闭缓冲区,就是关闭缓冲区的流对象
    br.close();
}

readLine()的原理

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200803084033131.png

LineNumberReader

BufferReader的子类,也是用于增强Read类功能的。但是增加了设置行号和获取行号的功能
在这里插入图片描述

class Demo {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("");
        LineNumberReader inr = new LineNumberReader(fr);
        inr.setLineNumber(0);
        String line= null;
        while((line=inr.readLine())!=null){
            System.out.println(inr.getLineNumber() + ":"+line);
        }
    }
}

FileOutputStream

写字节,可操作文件

public static void main(String[] args) throws IOException {
    FileOutputStream fi = new FileOutputStream("out.txt");
    // 使用字节流,没有使用缓存区的话不需要使用fi.flush()
    fi.write("s".getBytes());
    fi.close();
}

FileInputStream

读字节,可操作文件

    public static void main(String[] args) throws IOException {
        FileInputStream fi = new FileInputStream("a.txt");
        // 读一个字节
        fi.read();
        // 将字符读入byte数组
        byte[] buf = new byte[1024];
        int leng=0;
        while ((leng=fi.read(buf))!=-1){
            System.out.println(new String(buf, 0, leng));
        }
        // fi.available()  获取字节总数
        // 虚拟机启动,默认是64M内存。new 一个大的数组容易导致内存溢出,所以数据大时不建议使用此方式
        byte[] buf2 = new byte[fi.available()];
        fi.read(buf2);
        System.out.println(new String(buf2));
        fi.close();
    }

字节流缓存区

BufferedInputStream
BufferedOutputStream

public static void main(String[] args) throws IOException {
    BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("c:\\a.mp3"));
    BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\1.mp3"));
    int by = 0;
    // BufferedInputStream 中已经定义了byte数组,不需要再定义byte数组
    while ((by=bufis.read())!=-1){
        bufos.write(by);
    }
    bufis.close();
    bufos.close();
}

读取键盘录入

System.in: 对应的标准输入设备是键盘,返回类型为InputStream
System.out: 对应的标准输出设备是控制台
System.in和System.out属于字节流

InputStream in = System.in;
int by = 0;
try {
    by = in.read();
} catch (IOException e) {
    e.printStackTrace();
}
System.out.println(by);

读取转换流

· InputStreamReader是字符流
· InputStreamReader:是字节流转向字符流的桥梁
· 可以指定编码
· 构造方法
InputStreamReader(InputStream in) 创建一个使用默认字符集的 InputStreamReader。
InputStreamReader(InputStream in, String charsetName) 创建使用指定字符集的 InputStreamReader。
参数:InputStream in:字节输入流,用来读取文件中保存的字节;String charsetName:指定的编码表名称,不区分大小写,可以是utf-8/UTF-8,gbk/GBK,…不指定默认使用UTF-8

写入转换流

· OutputStreamWriter是字符流
· OutputStreamWriter是字符流通向字节流的桥梁
OutputStreamWriter流的作用就是利用字节流(OutputStream)作为”底层“输出流然后构建字符内输出流,字符输出流输出字符到流中,然后通过指定的字符集把流中的字符编码成字节输出到字节流中。
· 可以指定编码

public void hello() throws IOException {
        InputStream in = System.in;
        InputStreamReader isr = new InputStreamReader(in);
        BufferedReader br = new BufferedReader(isr);
   
        OutputStream os = System.out;
        OutputStreamWriter osw = new OutputStreamWriter(os);
        BufferedWriter bw = new BufferedWriter(osw);

        while (true){
            String a = null;
            if((a=br.readLine())=="over"){
                break;
            }
            bw.write(a);
            bw.newLine();
            bw.flush();
        }
    }

流操作的基本规律

一、
1、明确源和目的
源:输入流 InputStream Reader
目的:输出流 OutputStream Writer
2、明确操作的数据是否是纯文本
是:字符流
否:字节流
3、明确设备
输入设备:内存、硬盘、键盘
输出设备:内存、硬盘、控制台
二、常见需求:
1、将一个文本文件中的数据存储到另一个文本文件中
源:读取数据,可选InputStream Reader ;是纯文本,所以使用Reader;设备是硬盘文件,所以使用FileReader;提高效率使用BufferReader
BufferedReader br = new BufferedReader(new FileReader(“s.txt”));

目的:写数据,可选OutputStream Writer ;操作的是文件,所以使用Writer;设备是硬盘文件,所以使用FileWriter
BufferedWriter bw = new BufferedWriter(new FileWriter(“s.txt”));

2、将键盘录入的数据存储到文本文件中
源:读取数据,可选InputStream Reader ;是纯文本,所以使用Reader;设备是键盘,键盘是字节流(System.in),字节流转换字符流用InputStreamReader;提高效率使用BufferReader
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

目的:写数据,可选OutputStream Writer ;是纯文件,所以使用Writer;设备是硬盘文件,所以使用FileWriter
BufferedWriter bw = new BufferedWriter(new FileWriter(“s.txt”));

扩展:将键盘录入的数据按照指名的编码表 存储到文本文件中
FileWriter使用的是默认编码表GBK,只有转化流OutputStreamWriter可以指定编码表
目的:写数据,可选OutputStream Writer ;是纯文件,所以使用Writer;设备是硬盘文件,所以使用FileWriter;需要指定编码表,OutputStreamWrite可以指定编码;OutputStreamWriter的参数是字节输出流,OutputStreamWriter将字符流转换为字节流;FileOutputStream写字节,可操作文件。
BufferedWriter bw = new BufferedWriter(OutputStreamWriter(new FileOutputStream(“s.txt”), “utf-8”))

修改标准输入输出设备

System.setIn(new FileOutputStream(“ss.txt”));
System.setOut(new PrintStream(“aa.txt”));
可实现复制,不常用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值