JAVA学习小计之IO流02--字符流篇

字符流

字符流的由来:因为数据编码的不同,因而有了对字符进行高效操作的流对象,字符流本质其实就是基于字节流读取时,去查了指定的码表;而字节流直接读取数据会有乱码的问题(读中文会乱码),比如应对中文,每次就是读入一个字,而字节流在此情况下可能一次读取不了一个字,因为一个字不止一个字节

从另一角度来说:字符流 = 字节流 + 编码表

区别:

字符流,字符为单位读写数据,字符流专门用于处理文本文件。如果处理纯文本的数据优先考虑字符流,其他情况就只能用字节流了(图片、视频、等等)


字符输入流(Reader)

java.io.Reader抽象类是字符输入流的所有类的父类,可以读取字符信息到内存中

FileReader类:

  • java.io.FileReader类是读取字符文件类。
  • 构造时使用系统默认的字符编码和默认字节缓冲区。

FileReader的构造方法:

1、FileReader(File file)创建一个新的 FileReader ,给定要读取的File对象
2、 FileReader(String fileName) 创建一个新的 FileReader ,给定要读取的文件的字符串名称(推荐)

构造举例,代码如下:

public class FileReaderConstructor throws IOException{
    public static void main(String[] args) {
   	 	// 使用File对象创建流对象
        File file = new File("D:\code\JavaDemo\a.txt");
        FileReader fr = new FileReader(file);
      
        // 使用文件名称创建流对象
        FileReader fr = new FileReader("D:\code\JavaDemo\b.txt");
    }
}

 案例代码:

新建文本,名字为read,路径为D:\\code\\JavaDemo\\read.txt,内容为我是一个冷漠无情的机器人。

  1. 读取字符read方法,每次可以读取一个字符的数据,提升为int类型,读取到文件末尾,返回-1,循环读取,代码使用演示:
package com.logindemo.IO;

import java.io.FileReader;
import java.io.IOException;

public class readf1 {
    public static void main(String[] args) {
        FileReader fileReader = null;
        int data = 0;
        String path = "D:\\code\\JavaDemo\\read.txt";
        try {
            fileReader = new FileReader(path);
            //一次读取单个字符
            while ((data = fileReader.read()) != -1) {
                System.out.print((char) data);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                fileReader.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
2.利用数组,一次读取多个字符,这种方法更快
package com.logindemo.IO;

import java.io.FileReader;
import java.io.IOException;


public class readf2 {
    public static void main(String[] args) {
        FileReader fileReader = null;
        char[] data = new char[8];
        int len = 0;
        String path = "D:\\code\\JavaDemo\\read.txt";
        try {
            fileReader = new FileReader(path);
            //利用数组,一次读取多个字符,这种方法更快
            while ((len = fileReader.read(data)) != -1) {
                System.out.print(new String(data, 0, len));
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                fileReader.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

运行结果:读取正确~~~~


 

字符输出流(Writer)

java.io.Writer抽象类是字符输出流的所有类的超类(父类),将指定的字符信息写出到目的地

FileWriter类:

  • java.io.FileWriter类是写出字符到文件的类。
  • 构造时使用系统默认的字符编码和默认字节缓冲区

FileWriter构造方法:

1、 FileWriter(File file): 创建一个新的 FileWriter,给定要读取的File对象。
2、FileWriter(String fileName): 创建一个新的 FileWriter,给定要读取的文件的名称。(推荐)

public class FileWriterConstructor {
    public static void main(String[] args) throws IOException {
   	 	// 第一种:使用File对象创建流对象
        File file = new File("D:\code\JavaDemo\\a.txt");
        FileWriter fw = new FileWriter(file);
      
        // 第二种:使用文件名称创建流对象
        FileWriter fw = new FileWriter("D:\code\JavaDemo\\b.txt");
    }
}

案例代码:

package com.logindemo.IO;

import java.io.FileWriter;
import java.io.IOException;
// 文件输出流FileWriter案例:
public class writef1{
    public static void main(String[] args) {
        FileWriter fileWriter = null;
        String path = "D:\\code\\JavaDemo\\write.txt";
        char[] data = {'h', 'j'};
        try {
            //通过设置true变为追加模式
            fileWriter = new FileWriter(path, true);
            //fileWriter.write(1);
            fileWriter.write('H');   //当前内容:H
            fileWriter.write("吃饭了吗");   //当前内容:H吃饭了吗
            fileWriter.write("Island早上好", 0, 2);   //当前内容:H吃饭了吗Is
            fileWriter.write(data, 0, 1);   //当前内容:H吃饭了吗Ish
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            //必须要将写入流关闭,才能将数据成功写入,否则就是空文件
            try {
                fileWriter.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

 运行结果:写入成功~~~~

注意点 :

  • 注意这个方法必须要在最后关闭输出流,数据才会成功写入文件
  • 关闭资源时,与FileOutputStream不同。  因为内置缓冲区的原因,如果不关闭输出流,数据只是保存到缓冲区,无法保存到文件中
  • 但是关闭的流对象,是无法继续写出数据的。如果我们既想写出数据,又想继续使用流,就需要flush 方法了。

 flush  :刷新缓冲区,流对象可以继续使用。
 close :先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。

 怎么理解呢?我们直接来一个小案例:

package com.logindemo.IO;

import java.io.FileReader;
import java.io.FileWriter;

public class FlushDemo {
    public static void main(String[] args) throws Exception {
        // 使用文件名称创建流对象
        FileWriter fw = new FileWriter("D:\\code\\JavaDemo\\flush.txt");
        // 写出数据,通过flush
        fw.write('刷'); // 写出第1个字符
        fw.flush();
        fw.write('新'); // 继续写出第2个字符,写出成功
        fw.flush();

        // 写出数据,通过close
        fw.write('关'); // 写出第1个字符
        fw.close();
        fw.write('闭'); // 继续写出第2个字符,【报错】java.io.IOException: Stream closed
        fw.close();
    }
}

运行结果:可以看到使用flush后流对象可以继续使用,成功写入刷新,但是使用close后流对象不可以再被使用了!!直接报错了!写入也失败了

总结一下:

  • flush()这个函数是清空的意思,用于清空缓冲区的数据流;
  • 进行流的操作时,数据先被读到内存中,然后再用数据写到文件中,那么当你数据读完时,我们如果这时调用close()方法关闭读写流,这时就可能造成数据丢失,为什么呢?因为,读入数据完成时不代表写入数据完成,一部分数据可能会留在缓存区中,这个时候flush()方法就格外重要了。 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值