合并流以后,操作可以是读写到另一个文件,或者打印到控制台。下面看代码:
package javaS.IO; +import java.io.FileInputStream; public class SequenceInputStreamS extends IOBaseS { /** * 合并两个读入的字节流 * * @throws IOException */ @Test public void testSequenceInputStream() throws IOException { // buffer的空间要设定为2的次方才能有效分割,否则会出现某汉字被中途分割显示不完整的情况, int bufferSize = 16; InputStream is1 = new FileInputStream(root + "UME.txt"); InputStream is2 = new FileInputStream(root + "HongXing.txt"); SequenceInputStream sis = new SequenceInputStream(is1, is2);// 构造参数必须为InputStream byte[] buffer = new byte[bufferSize]; while (sis.read(buffer, 0, bufferSize) != -1) { // 开始读合并后的数据流,这里可以针对这些数据流做任何操作(读写到任何文件或者打印到控制台) String str = new String(buffer, 0, bufferSize); logger.info(str);// 打印到控制台 } is1.close(); is2.close(); sis.close(); } @Test public void testMergeEnumInputStream() throws IOException { // 实际上它可以合并不同类型数据,然而如果是对象流的话,读取时涉及反序列化工作,要找准与其他数据的分割点,比较麻烦。 InputStream is1 = new FileInputStream(root + "UME.txt"); InputStream is2 = new FileInputStream(root + "HongXing.txt"); InputStream is3 = new FileInputStream(root + "HuaYi.txt"); ArrayList<InputStream> list = new ArrayList<InputStream>(); list.add(is1); list.add(is2); list.add(is3); Iterator<InputStream> it = list.iterator();// 传入一个迭代器用于创建枚举 SequenceInputStream sis = new SequenceInputStream(new Enumeration<InputStream>() { @Override public boolean hasMoreElements() { return it.hasNext(); } @Override public InputStream nextElement() { return it.next(); } }); int bufferSize = 32; byte[] buffer = new byte[bufferSize]; while (sis.read(buffer, 0, bufferSize) != -1) { // 开始读合并后的数据流,这里可以针对这些数据流做任何操作(读写到任何文件或者打印到控制台) String str = new String(buffer, 0, bufferSize); logger.info(str);// 打印到控制台 } is1.close(); is2.close(); is3.close(); sis.close(); } } 六、LineNumberReaderLineNumberReader是可以将读入的字符流加入行号,下面看代码。
package javaS.IO; import java.io.FileReader; import java.io.IOException; import java.io.LineNumberReader; import org.junit.Test; public class LineNumberReaderS extends IOBaseS { @Test public void testLineNumberReader() throws IOException { FileReader fr = new FileReader(root + "UME.txt"); // 构造参数为Reader LineNumberReader lnr = new LineNumberReader(fr); lnr.setLineNumber(1);// 设置行号从2开始。 String str; while ((str = lnr.readLine()) != null) { // 核心方法:lnr.getLineNumber(),获得行号 logger.info("行号:" + lnr.getLineNumber() + " 内容:" + str); } fr.close(); lnr.close(); /** * 输出: * * 12:11:27[testLineNumberReader]: 行号:2 内容:举杯邀明月 * * 12:11:27[testLineNumberReader]: 行号:3 内容:床前明月光 */ } } 七、数组IO / PushbackInputStream / PushbackReader把单一字符推回输入流。这里采用了数组的读取方法,同样分为字节和字符,字节数组流为ByteArrayInputStream,字符数组流为CharArrayReader。
package javaS.IO; import java.io.ByteArrayInputStream; import java.io.CharArrayReader; import java.io.IOException; import java.io.PushbackInputStream; import java.io.PushbackReader; import org.junit.Test; public class PushBackS extends IOBaseS { @Test public void testPushbackInputStream() throws IOException { String content = "Superman VS Batman"; // 构造参数为一个字节数组 ByteArrayInputStream bais = new ByteArrayInputStream(content.getBytes()); // 构造参数为一个InputStream对象。 PushbackInputStream pbis = new PushbackInputStream(bais); pbis.unread("Ssdfasdf".getBytes(), 0, 1);// 将S推到源字符串的最前方 // pr.unread('S');// 这里的'S'是按照整型值操作 int n; String str = ""; while ((n = pbis.read()) != -1) { str += (char) n; // pbis.unread(n);将刚读出来的字符再推回去,就会死循环。 } logger.info(str); pbis.close(); bais.close(); /** * 输出: * * 12:32:48[testPushBackInputStream]: SSuperman VS Batman */ } @Test /** * PushbackInputStream的字符流版本 */ public void testPushbackReader() throws IOException { // 构造参数为Reader对象,使用字符数组读取 PushbackReader pr = new PushbackReader(new CharArrayReader("go go Gan.".toCharArray())); pr.unread("Ssdfasdf".toCharArray(), 0, 1);// 将S推到源字符串的最前方 // pr.unread('S');// 这里的'S'是按照整型值操作 int n; String str = ""; while ((n = pr.read()) != -1) { str += (char) n; // pr.unread(n);将刚读出来的字符再推回去,就会死循环。 } logger.info(str); pr.close(); /** * 输出: * * 12:45:55[testPushbackReader]: Sgo go Gan. */ } } 八、StringWriter / StringReader