【Java IO】 四、Writer和Reader源码阅读

20160421004327228.png

##1.Writer
官方描述: 写入字符流的抽象类。子类必须实现的方法仅有 write(char[], int, int)、flush() 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。

#####继承了三个接口

public abstract class Writer implements Appendable, Closeable, Flushable {


//缓存区 ,如欲写入String/CharSequence将使用该buffer
    private char[] writeBuffer;
//默认的大小,如写入的String大于该缓冲区,则会新建相应大小的buffer
    private static final int WRITE_BUFFER_SIZE = 1024;

  
    protected Object lock;

    protected Writer() {
        this.lock = this;
    }

    protected Writer(Object lock) {
        if (lock == null) {
            throw new NullPointerException();
        }
        this.lock = lock;
    }

    public void write(int c) throws IOException {
//加锁
        synchronized (lock) {
//如果buffer未初始化,则初始化
            if (writeBuffer == null){
                writeBuffer = new char[WRITE_BUFFER_SIZE];
            }
//将 写入的int c 的char值写入到 char数组中
            writeBuffer[0] = (char) c;
            write(writeBuffer, 0, 1);
        }
    }
//调用抽象的方法
    public void write(char cbuf[]) throws IOException {
        write(cbuf, 0, cbuf.length);
    }

//**核心方法**,将char数组中的内容写入流中,需子类实现
    abstract public void write(char cbuf[], int off, int len) throws IOException;


    public void write(String str) throws IOException {
        write(str, 0, str.length());
    }

    public void write(String str, int off, int len) throws IOException {
//加锁
        synchronized (lock) {
//一个chars数组,用来将String放入,再调用write(char cbuf[])
            char cbuf[];
//欲写入的字符串长度如果小于buffer,就使用默认的buffer,如果大于,就创
//建len长度的char[]
            if (len <= WRITE_BUFFER_SIZE) {
                if (writeBuffer == null) {
                    writeBuffer = new char[WRITE_BUFFER_SIZE];
                }
                cbuf = writeBuffer;
            } else {    // Don't permanently allocate very large buffers.
                cbuf = new char[len];
            }
            str.getChars(off, (off + len), cbuf, 0);
//调用抽象的方法,需子类进行实现
            write(cbuf, 0, len);
        }
    }


    public Writer append(CharSequence csq) throws IOException {
        if (csq == null)
            write("null");
        else
            write(csq.toString());
        return this;
    }

    public Writer append(CharSequence csq, int start, int end) throws IOException {
        CharSequence cs = (csq == null ? "null" : csq);
        write(cs.subSequence(start, end).toString());
        return this;
    }

    public Writer append(char c) throws IOException {
        write(c);
        return this;
    }
//子类需实现
    abstract public void flush() throws IOException;

    abstract public void close() throws IOException;

##1.Reader


public abstract class Reader implements Readable, Closeable {


    protected Object lock;

//将new出的对象的引用赋值给lock
    protected Reader() {
        this.lock = this;
    }

 //用一个给定的对象来实现同步
    protected Reader(Object lock) {
        if (lock == null) {
            throw new NullPointerException();
        }
        this.lock = lock;
    }

 //将流读入到buffer中
    public int read(java.nio.CharBuffer target) throws IOException {
        int len = target.remaining();
        char[] cbuf = new char[len];
        int n = read(cbuf, 0, len);
        if (n > 0)
            target.put(cbuf, 0, n);
        return n;
    }

 //读一个单独的字符
    public int read() throws IOException {
        char cb[] = new char[1];
        if (read(cb, 0, 1) == -1)
            return -1;
        else
            return cb[0];
    }


    public int read(char cbuf[]) throws IOException {
        return read(cbuf, 0, cbuf.length);
    }

//**核心方法**,将流读入字符数组,返回读入的字符个数, 需子类实现
    abstract public int read(char cbuf[], int off, int len) throws IOException;


    private static final int maxSkipBufferSize = 8192;

    private char skipBuffer[] = null;


    public long skip(long n) throws IOException {
        if (n < 0L)
            throw new IllegalArgumentException("skip value is negative");
        int nn = (int) Math.min(n, maxSkipBufferSize);
        synchronized (lock) {
            if ((skipBuffer == null) || (skipBuffer.length < nn))
                skipBuffer = new char[nn];
            long r = n;
            while (r > 0) {
                int nc = read(skipBuffer, 0, (int)Math.min(r, nn));
                if (nc == -1)
                    break;
                r -= nc;
            }
            return n - r;
        }
    }

//这个流是否准备好被读
    public boolean ready() throws IOException {
        return false;
    }

 //是否支持mark操作
    public boolean markSupported() {
        return false;
    }


    public void mark(int readAheadLimit) throws IOException {
        throw new IOException("mark() not supported");
    }

    public void reset() throws IOException {
        throw new IOException("reset() not supported");
    }

//关闭该流,释放占用的资源
     abstract public void close() throws IOException;

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的 Java 记账本程序的源代码,包括使用 IO 流进行文件读写操作: ```java import java.io.*; import java.util.Scanner; public class AccountBook { private static final String FILENAME = "accountbook.txt"; public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while (true) { System.out.println("请选择操作:\n1. 查看记录\n2. 添加记录\n3. 退出"); int choice = scanner.nextInt(); if (choice == 1) { try (BufferedReader reader = new BufferedReader(new FileReader(FILENAME))) { String line; while ((line = reader.readLine()) != null) { System.out.println(line); } } catch (IOException e) { System.out.println("读取文件失败!"); } } else if (choice == 2) { System.out.print("请输入记录:"); String record = scanner.next(); try (BufferedWriter writer = new BufferedWriter(new FileWriter(FILENAME, true))) { writer.write(record + "\n"); System.out.println("记录添加成功!"); } catch (IOException e) { System.out.println("写入文件失败!"); } } else if (choice == 3) { break; } else { System.out.println("无效的选择!"); } } } } ``` 该程序使用了一个常量 `FILENAME` 来表示保存记录的文件名,包含了以下三个主要操作: 1. 查看记录:使用 `BufferedReader` 从文件中读取每一行记录并输出到控制台。 2. 添加记录:使用 `BufferedWriter` 向文件中写入一条记录。 3. 退出:退出程序循环。 在添加记录时,使用了 `FileWriter` 的构造函数的第二个参数 `true`,表示打开文件时追加而不是覆盖原有内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值