Java I/O体系(二)
接着上一篇的内容,我们来继续学习一下Java I/O里其它的类;我们一对儿一对儿的来学习这些类,除了某些奇葩,Let’s go!
1. 管道流(PipedInputStream、PipedOutputStream)
提到管道,就有画面感了,水管套水管,水管接水管;它有一个特点,那就是,一旦两个管道流连接之后,只要是忘管道里面写数据流的线程没有完成写入,另一边读取数据流的线程就会一直在读取处挂起(),直到写线程完成写入。打个不太恰当的比方,就好像两个水管工在接水管(诶?好像有什么奇怪的东西混进来了),要确定有没有接好,就必须要上游的水管工把水源接好,再问下游的水管工有没有水流到他那儿,如果水没有留到下游,下游的水管工就要一直等啊等,知道水流到他那儿,才能算完成任务。
这个不恰当的比喻体现到代码里就是这样的:
package learn.io;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
/**下游水管工*/
class MyPipeReader extends Thread {
PipedInputStream pipeIn;
public MyPipeReader(PipedInputStream pipeIn) {
super();
this.pipeIn = pipeIn;
}
public PipedInputStream getPipeIn() {
return pipeIn;
}
@Override
public void run() {
System.out.println("我是下游水管工");
try {
byte[] b = new byte[1024];
/* 看看有没有水从上游流下来 */
int length = pipeIn.read(b);
String result = new String(b, 0, length);
System.out.println(result);
System.out.println("下游水管工:有水流出来啦!");
pipeIn.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**上游水管工*/
class MyPipeSender extends Thread {
PipedOutputStream pipeOut;
public MyPipeSender(PipedOutputStream pipeOut) {
super();
this.pipeOut = pipeOut;
}
public PipedOutputStream getPipeOut() {
return pipeOut;
}
@Override
public void run() {
System.out.println("我是上游水管工");
String result = "我是水";
try {
/* 在这里让线程睡眠3秒钟,模拟水在水管里面流的时间 */
Thread.sleep(3000);
/* 上游开始放水 */
System.out.println("上游水管工:开闸放水");
pipeOut.write(result.getBytes());
pipeOut.close();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**测试*/
public class PipedStreamTest {
public static void main(String[] args) {
/*创建两个需要连接的水管*/
PipedInputStream pipeIn = new PipedInputStream();
PipedOutputStream pipeOut = new PipedOutputStream();
/* 创建管道工 */
MyPipeReader myPipeIn = new MyPipeReader(pipeIn);
MyPipeSender myPipeOut = new MyPipeSender(pipeOut);
/* 连接两个管道工各自的管道 */
try {
myPipeOut.getPipeOut().connect(myPipeIn.getPipeIn());
} catch (IOException e) {
e.printStackTrace();
}
/* 连接完成后就可以放水测试一下了 */
myPipeIn.start();
myPipeOut.start();
}
}
输出结果为:
我是上游水管工
我是下游水管工
上游水管工:开闸放水
我是水
下游水管工:有水流出来啦!
当然,大水管可以套小水管,管道流也可以嵌套其他的流这里就不举例了,用法和前面例子里的InputStream和OutputStream的嵌套使用是差不多的。
2. StringReader类和StringWriter类
这两个类主要是对字符串的操作(看名字就知道o(^▽^)o),话不多说,直接举个字符串转换大小写的例子就好:
package learn.io;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
public class StringReaderTest {
public static void main(String[] args) {
String str = "abcdefghijklmn";
transform(str);
}
/** 转换大小写 */
public static void transform(String str) {
StringReader sr = new StringReader(str);
StringWriter sw = new StringWriter();
char[] chars = new char[1024];
try {
int len = 0;
while ((len = sr.read(chars)) != -1) {
String strRead = new String(chars, 0, len).toUpperCase();
// 输出
System.out.println(strRead);
sw.write(strRead);
sw.flush();
}
sr.close();
sw.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
sr.close();
try {
sw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
输出:
ABCDEFGHIJKLMN
用法还是比较简单的。
这一篇先到这里,欲知后事如何,请看下回分解!