Java IO流之StringWriter和StringReader用法分析

这篇文章主要介绍了Java IO流之StringWriter和StringReader用法分析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

简介

StringWriter和StringReader分别继承自Writer和Reader抽象类,作用就是将字符串String类型适配到StringWriter和StringReader类.

其中StringWriter实际上是用StringBuffer实现的,StringBuffer是一个线程安全的类,实际上默认的是16个字符的char数组.所以通过方法write()和append()等其他重载的方法.将字符串添加到StringBuffer中,可以调用toString()或者getBuffer()方法显示StringWriter流中所有的数据.其中close()方法和flush()方法,无实际的功能,只是简单的继承.

StringReader的有参构造方法传入的是String类型的数据,通过read()重载方法读取流中部分或者全部的字符内容.

StringWriter介绍

1.构造方法

 public StringWriter() {} public StringWriter(int initialSize) {}

无参构造方法,创建的是默认大小为StringBuffer的StringWriter流,其中StringBuffer底层实际是一个字符数组,默认大小是16个字符.

有参构造方法,创建的是指定大小的StringBuffer的StringWriter流,也就是指定initialSize个字符的字符数组.

2.内部变量

 private StringBuffer buf;

StringWriter流中缓冲区实际上通过StringBuffer来实现的.

3. 内部方法

 public void write(int c) {} public void write(char cbuf[], int off, int len){} public void write(String str) {} public void write(String str, int off, int len){} public StringWriter append(CharSequence csq){} public StringWriter append(CharSequence csq, int start, int end){} public StringWriter append(char c){} public String toString() {} public StringBuffer getBuffer() {} public void flush() {} public void close() {}
  • write(int c)---将单个字符写到流中.
  • write(char cbuf[] ,int off,int len)---将字符数组cbuf中off开始,len个字符写到流中.
  • write(String str)---将字符串str写到流中.
  • write(String str,int off,int len)---将字符串str中off位置开始,len个字符写到流中.
  • append(charsequence csq)---将字符序列csq写到流中.
  • append(charsequence csq,int start ,int end)----将字符序列中start到end之间字符写到流中.
  • append(char c)---将单个字符写到流中.
  • toString()---将流中所有字符转换成字符串返回.
  • getBuffer()----将流中内容,实际是StringBuffer返回.
  • flush()---仅仅是继承,方法内没有任何实现.
  • close()----仅仅是继承,方法内没有任何实现.

StringReader介绍

1.构造方法

 public StringReader(String s) {}

有参构造方法,传入的实际上是流中内容为字符串s.

2.内部变量

 private String str; private int length; private int next = 0; private int mark = 0;
  • str---StringReader流中实际的数据就是通过构造方法传入的字符串str.
  • length---流中字符串的长度.
  • next---要读取的下一个字符的位置.
  • mark---标记字符位置,调用mark()方法会将当前位置保存到mark中.

3. 内部方法

 private void ensureOpen(){} public int read(){} public int read(char cbuf[], int off, int len){} public long skip(long ns){} public boolean ready(){} public boolean markSupported() {} public void mark(int readAheadLimit){} public void reset(){} public void close(){}
  • ensureOpen()---确保流没有关闭,实际判断是流中内容字符串str不为null.
  • read()---从流中读取一个字符.
  • read(char cbuf[],int off,int len)---将流中最多len个字符读取到字符数组cbuf中,cbuf中从off开始.
  • skip(long ns)---跳过ns个字符.
  • ready()---流是否准备读取.
  • markSupported()---是否支持标记
  • mark(int readAheadLimit)---标记当前位置,readAheadLimit表示的是在标记有效情况下,从当前位置开始可取的最大字符数.
  • reset()---将流中当前位置重置到标记位置.
  • close()---关闭流,实际上是将流中内容字符串str置为null.

案例

 public class StringWriterDemo { public static void main(String[] args) throws IOException { testStringWriter(); testStringReader(); testOfAnotherStringWriter(); } //测试StringWriter private static void testStringWriter() throws IOException { StringWriter sw = new StringWriter(); sw.append("this is a"); sw.write("demo of StringWriter"); System.out.println(sw.toString()); sw.close(); } //测试StringReader private static void testStringReader() throws IOException { String content = "this is a demo of StringReader"; StringReader sr = new StringReader(content); int c; while((c=sr.read())!=-1) { System.out.println((char)c); } sr.close(); } //将读取的数据先写到StringWriter流中,然后直接调用toString()方法打印结果 private static void testOfAnotherStringWriter() throws IOException { FileReader fr = new FileReader("D:\\java.txt"); BufferedReader br = new BufferedReader(fr); StringWriter sw = new StringWriter(); int n; char cbuf[] = new char[1024]; while((n=br.read(cbuf))!=-1) { sw.write(cbuf, 0, n); } System.out.println(sw.toString()); fr.close(); br.close(); } }

源码分析

1.StringWriter源码分析

 public class StringWriter extends Writer { //StringWriter中缓冲功能是通过StringBuffer来实现的. private StringBuffer buf; //创建默认缓冲为16个字符的StringWriter.默认的StringBuffer实际是大小为16个字符的字符数组. public StringWriter() { buf = new StringBuffer(); lock = buf; } //创建指定大小StringBuffer的StringWriter,也就是指定了initialSize个字符的字符数组. public StringWriter(int initialSize) { if (initialSize <0) { throw new IllegalArgumentException("Negative buffer size"); } buf = new StringBuffer(initialSize); lock = buf; } //向流写入单个字符c public void write(int c) { buf.append((char) c); } //将字符数组cbuf中off位置开始,len个字符写到流中 public void write(char cbuf[], int off, int len) { if ((off <0) || (off > cbuf.length) || (len <0) || ((off + len) > cbuf.length) || ((off + len) <0)) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return; } buf.append(cbuf, off, len); } //将字符串str写到流中 public void write(String str) { buf.append(str); } //将字符串str中off位置开始,len个字符写到流中 public void write(String str, int off, int len)  { buf.append(str.substring(off, off + len)); } //将字符序列csq添加到流中. public StringWriter append(CharSequence csq) { if (csq == null) write("null"); else write(csq.toString()); return this; } //将字符序列csq中start位置到end之间的字符添加到流中 public StringWriter append(CharSequence csq, int start, int end) { CharSequence cs = (csq == null ? "null" : csq); write(cs.subSequence(start, end).toString()); return this; } //向流中添加一个字符c public StringWriter append(char c) { write(c); return this; } //将流中字符转换成字符串返回. public String toString() { return buf.toString(); } //返回流的内容,即StringBuffer public StringBuffer getBuffer() { return buf; } //刷新流,没有具体实现. public void flush() { } //关闭流后读取数据不会抛出异常,因为没有具体实现 public void close() throws IOException { } }

2,StringReader源码分析

 public class StringReader extends Reader { //流中实际数据就是通过构造方法传入str字符串. private String str; //字符串str的长度 private int length; //下一个要读取字符的位置. private int next = 0; //标记的位置. private int mark = 0; //创建一个StringReader流,参数传入的是字符串s public StringReader(String s) { this.str = s; this.length = s.length(); } //确保流没有关闭,实际判断的是StringReader构造方法是否有传入字符串. private void ensureOpen() throws IOException { if (str == null) throw new IOException("Stream closed"); } //读取单个字符 public int read() throws IOException { synchronized (lock) { ensureOpen(); if (next >= length) return -1; return str.charAt(next++); } } //将缓冲区中最多len个字符写到字符数组cbuf中,位置从off开始,长度为len个 public int read(char cbuf[], int off, int len) throws IOException { synchronized (lock) { ensureOpen(); //检测参数的合法性 if ((off <0) || (off > cbuf.length) || (len <0) || ((off + len) > cbuf.length) || ((off + len) <0)) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; } //超过字符串的长度,返回-1 if (next >= length) return -1; //剩余可读取的字符为length-next, //如果len超过剩余可读取字符,实际只能读取剩余可读取字符 //如果len小于剩余可读取字符,实际上读取的是len个字符 int n = Math.min(length - next, len); str.getChars(next, next + n, cbuf, off); next += n; return n; } } //跳过ns个字符,返回跳过的字符数 public long skip(long ns) throws IOException { synchronized (lock) { ensureOpen(); if (next >= length) return 0; // Bound skip by beginning and end of the source //缓冲区中剩余字符数与要跳过的字符数比较.取较小值 long n = Math.min(length - next, ns); n = Math.max(-next, n); next += n; return n; } } //流是否准备读取. public boolean ready() throws IOException { synchronized (lock) { ensureOpen(); return true; } } //流是否支持标记 public boolean markSupported() { return true; } //标记缓冲区中当前位置,readAheadLimit表示的是在保留标记的情况下,最大可读取的字符数 public void mark(int readAheadLimit) throws IOException { if (readAheadLimit <0){ throw new IllegalArgumentException("Read-ahead limit <0"); } synchronized (lock) { ensureOpen(); mark = next; } } //将缓冲区当前位置重置到标记位置 public void reset() throws IOException { synchronized (lock) { ensureOpen(); next = mark; } } //关闭流,释放相关资源(实际只是将流中内容字符串置为空) public void close() { str = null; } } 

以上为个人经验,希望能给大家一个参考,也希望大家多多支持0133技术站。

以上就是Java IO流之StringWriter和StringReader用法分析的详细内容,更多请关注0133技术站其它相关文章!

赞(0) 打赏
未经允许不得转载:0133技术站首页 » Java