本教程 *** 作环境:windows7系统、java10版,DELL G3电脑。
1.创建和连接管道两端的两种方法
(1)创建管道输入和输出流并连接它们。它使用connect方法连接两个流。
PipedInputStream pis = new PipedInputStream(); PipedOutputStream pos = new PipedOutputStream(); pis.connect(pos);
(2)创建管道输入和输出流并连接它们。它通过将输入管道流传递到输出流构造器来连接两个流。
PipedInputStream pis = new PipedInputStream(); PipedOutputStream pos = new PipedOutputStream(pis);
2.写入报错分析
在线程Sender中向管道流中写入一个字符串,写入后关闭该管道流;在线程Reciever中读取该字符串。
import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class PipedStreamExam1 { public static void main(String[] args) { ExecutorService executorService = Executors.newCachedThreadPool(); try { //创建管道流 PipedOutputStream pos = new PipedOutputStream(); PipedInputStream pis = new PipedInputStream(pos); //创建线程对象 Sender sender = new Sender(pos); Reciever reciever = new Reciever(pis); //运行子线程 executorService.execute(sender); executorService.execute(reciever); } catch (IOException e) { e.printStackTrace(); } //等待子线程结束 executorService.shutdown(); try { executorService.awaitTermination(1, TimeUnit.DAYS); } catch (InterruptedException e) { e.printStackTrace(); } } static class Sender extends Thread { private PipedOutputStream pos; public Sender(PipedOutputStream pos) { super(); this.pos = pos; } @Override public void run() { try { String s = "This is a good day. 今天是个好天气。"; System.out.println("Sender:" + s); byte[] buf = s.getBytes(); pos.write(buf, 0, buf.length); pos.close(); } catch (IOException e) { e.printStackTrace(); } } } static class Reciever extends Thread { private PipedInputStream pis; public Reciever(PipedInputStream pis) { super(); this.pis = pis; } @Override public void run() { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buf = new byte[1024]; int len = 0; while ((len = pis.read(buf)) != -1) { baos.write(buf, 0, len); } byte[] result = baos.toByteArray(); String s = new String(result, 0, result.length); System.out.println("Reciever:" + s); } catch (IOException e) { e.printStackTrace(); } } } }
注意,若管道流没有关闭,则使用这种方法读取管道中的信息会报错:
while ((len = pis.read(buf)) != -1) { baos.write(buf, 0, len); }
错误代码为java.io.IOException: Write end dead;发生这个错误的原因在于,由于管道未关闭,所以read语句不会读到-1,因此PipedInputStream会持续从管道中读取数据,但是因为Sender线程已经结束,所以会抛出“Write end dead”异常。
以上就是java管道流写入报错的原因分析,这是因为线程结束而管道流持续作用的结果。下次大家在使用的时候,需要注意多线的运行状态,避免此类报错的产生。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)