技术文章 > java >  java基础 > 正文

java管道流写入报错

小妮浅浅

在使用管道流时,如果写入后对该通道进行关闭,就会出现报错的情况。那么具体出错的原理,想必很多人不清楚,关于这点在线程的操作时有讲到,管道存在于线程中。下面我们就先来学习管道创建的方法,然后进行对线程的关闭测试,在其中找到管道流报错的原因。

1.创建和连接管道两端的两种方法

1)创建管道输入和输出流并连接它们。它使用connect方法连接两个流。

PipedInputStream pis  = new PipedInputStream(); 
PipedOutputStream pos  = new PipedOutputStream(); 
pis.connect(pos); /* Connect  the   two  ends  */

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管道流写入报错的原因分析,这是因为线程结束而管道流持续作用的结果。下次大家在使用的时候,需要注意多线的运行状态,避免此类报错的产生。

免费视频教程
本文原创发布python学习网,转载请注明出处,感谢您的尊重!
相关文章
 IO流序列化在java中的作用及不足
 java中断机制解决办法
 java缓冲流的两种类型
 java中的轮换流是什么
 转换流在java中的两种类
 java打印流的输出使用
 java管道流发送线程
相关视频章节
 网络爬虫
 云端部署Web应用程序视频
 Web应用框架Flask和文件模板
 Web应用程序开发概述
 继承和多态
推荐视频
视频教程分类