「管道实现java」管道的实现

博主:adminadmin 2022-12-31 06:27:07 1176

今天给各位分享管道实现java的知识,其中也会对管道的实现进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

JXTA Platform JAVA参考实现源代码分析(2)

引言 管道的概念源于Unix 是不同线程之间直接传输数据的基本手段 JDK中java io包中就有管道类 同时 管道在JXTA中是最基本的概念 是对等点之间的数据传输的主要方式 对等管道协议(PBP)明确规范了对等管道的绑定 解析 响应 本文依次剖析集中式(JDK)和对等环境下(JXTA)管道的实现方式 对比分析其异同 然后尝试在JXTA中建立一个虚拟的全双工的管道 本文的目标是通过对不同环境下管道的实现方式对比分析 来理解为什么JXTA采用管道作为基本的数据传输手段 管道的形象化描述 一个生活中的情景 现在有两个地区A B A是石油生产区 B是石油消费区 现在B地区需要消费A地区的石油 当然可以通过海运 空运获得 然而最通常的方式是架设输油管道 如图所示   引言 管道的概念源于Unix 是不同线程之间直接传输数据的基本手段 JDK中java io包中就有管道类 同时 管道在JXTA中是最基本的概念 是对等点之间的数据传输的主要方式 对等管道协议(PBP)明确规范了对等管道的绑定 解析 响应 本文依次剖析集中式(JDK)和对等环境下(JXTA)管道的实现方式 对比分析其异同 然后尝试在JXTA中建立一个虚拟的全双工的管道 本文的目标是通过对不同环境下管道的实现方式对比分析 来理解为什么JXTA采用管道作为基本的数据传输手段 管道的形象化描述 一个生活中的情景 现在有两个地区A B A是石油生产区 B是石油消费区 现在B地区需要消费A地区的石油 当然可以通过海运 空运获得 然而最通常的方式是架设输油管道 如图所示 java中流的概念和管道的概念都可以通过此案例阐述 A与B之间连接的就是管道 负责将A的石油向B输出 A向管道输出数据(output) B从管道输入数据(input) 可以这样理解 管道是A的输出对象 是B的数据源 这里就产生了三个类 输出流A 输入流B 管道 输入流B负责如何获取数据(read 操作) 输出流A负责如何消费数据(write操作) 管道负责连接它们(connect 操作) 其实 在实现时 管道类分解为管道口 管道出口 由入口出口负责连接 在复杂的网络环境中 这种连接方式可以有专门的网络协议负责(例如 JXTA中的PBP 全称Pipe Bind Protocol) 由以上描述 我们可以清楚知道最原始的管道就是单向的 文章后面介绍的双向管道 是用两个单向管道虚拟的 而非真实的连接方式 不难发现管道最关键的问题是如何协调输出(A)与输入(B) 这在不同的网络环境会遇到不同的问题 最简单的是同一JVM下的不同过程(线程或任务)之间用同步方式传递数据 而对等环境下 如何去发现对方就是一个很现实的问题 这仅仅只是问题的其中之一 下面的章节会依次分析 集中式环境下管道的实现 问题的描述 A与B是在同一JVM中 A B有一方能够发现另一方的存在 A将数据发往B方 A发送数据与B接收数据是相互独立的 现在回到问题的最初 为什么要使用管道?A只管发送 B只管接受 那么数据在哪儿呢?经过下面的分析 就会明白管道把管理数据缓冲区的重任交给了他自己 A B均是围绕这个缓冲区来启停线程的 显然这才是问题的本质 JDK中 类PipeInputStream(即前面所述的B)与PipeOutputStream(即前面所述的的A)可以很好的解决这一问题 首先给出类图如下   下面是将类PipeOutputStream的connect方法代码简化后给予注释 public synchronized void connect(PipedInputStream snk) throws IOException { sink = snk; //将PipeInputStream的实例作为PipeOutputStream的一个属性 以便调用 snk in = ;//缓冲区的输入位置 表示缓冲区为空 snk out = ;//缓冲区的输出位置nnected = true;}连接以后 PipeOutputStream的write操作直接调用sink receive(b);这样 对缓冲区buffer的维护 就变成了read()和receive()操作之间的线程同步 JDK对缓冲区的处理非常巧妙 采用了循环列表 它用缓冲区的标志位的变化来代替数据的移动 类似于生活中的时钟把线性的时间规范为 小时来表示 这不属于本文的论述范围 就不继续分析了 read操作 正常情况下 从out位置读取数据 缓冲区空时进入等待状态 以轮询的方式( 秒间隔)来自我释放 receive操作 正常情况下 向in位置写入数据 缓冲区满时进入等待状态 同样 以轮询的方式( 秒间隔)来自我释放 JXTA对等管道的实现 通过对JDK的分析 我们可以了解到在集中式环境下 管道的架设方案是比较简单的 在对等环境下(分布式环境下也类似) 出于同样的目标 遇到的问题却在急剧的扩大 例如 管道入口和出口之间如何相互发现?数据如何保证在不同的环境下传送?甚至 对管道本身的概念发生质疑 一定是单入口 单出口吗?JXTA规范中 管道是在端点之上的服务或应用之间发送和接收信息的虚拟连接通道 管道提供在对等端点传输之上的网络抽象 管道有点到点和广播两种通信模式 JXTA是通过管道广告来唯一标示管道的 输出管道要找到与其广告相同的输入管道才能发送数据 广告内容如下!DOCTYPE jxta:PipeAdvertisementjxta:PipeAdvertisement xmlns:jxta= ; Idurn:jxta:uuid A E AE ABBE EF CBE /Id Type JxtaUnicast /Type Name PipeExample /Name/jxta:PipeAdvertisement如果您需要对JXTA管道有实例化的概念 请参考Sing Li的使p p能进行交互操作 Jxta命令shell 这篇文章有部分内容专门介绍了如何在通过shell使用管道 本文主要是从编程的视角去看管道是如何实现的 客户视角Project JXTA : Java Programmer s Guide Chapter 有个例子阐述如何去在对等点之间发送信息 读者可以到下载源码 现在从客户视角简要的分析它的传送原理 要深入的了解可以看下一节的系统视角分析 该例中 有两个对等点 并且构建了两个不同的类 一个负责接收(Pipelistener) 一个负责发送(PipeExample) 具体的接收次序可以参考时序图  educity cn/img_ / / / gif 类Pipelistener实现了接口PipeMsgListener 类PipeExample实现了接口OutputPipeListener 由时序图(这是两个JVM中的类 所以时序符号是独立标示的)可以清晰的获知 各个对等点的前 步是相互独立的 各自的第 步 采用回调的方式建立输入和输出管道 一旦对等系统探测到对方的存在 就分别触发各自的事件发送或接收消息 显然JXTA中管道是异步的 调试该例程时 注意先建立输入管道 然后建立输出管道 因为 输出管道在一定的时间和次数内探测不到输入管道的存在 就会主动放弃 否则 容易让网络系统在这些无休止的探测中瘫痪 系统视角从上面的例程中 可以了解对等管道的创建方法 以及数据流程 但是不能明确对等系统是如何去实现的 JXTA中管道的实现比在JDK中实现要复杂得多 具体的技术标准可以参考对等管道绑定协议(PBP) 此协议规范了JXTA中管道的概念 但并没有涉及到如何去实现 这同样是所有JXTA协议的特征 它们的目标是阐述what it is 而把how to do it留给开发者 这样有利于增强系统的开放性 其中Java参考实现 就是该协议实现的一个案例 以下将具体分析 首先看管道实现的类图(以单播为例)  educity cn/img_ / / / gif 关键的类  InputPipeImpl 输入管道的实现类 NonBlockingOutputPipe 输出管道的实现类 PipeServiceImpl 管道服务的实现类 负责创建输入输出管道 PipeResolver 提供管道绑定的解析服务 通过客户视角的分析 可以得知系统外部是通过PipeServiceImpl来获取输入输出管道 那么消息是如何在对等系统中通过管道过滤和传递的? 从程序实现的角度 涉及到太多的技术细节 JXTA的参考实现中有着庞杂的监听系统 本文尝试用一个案例从两个层次去解析这个问题 两个层次分别是消息的具体形式 服务和端点协议的具体分发策略 很显然 这里我们把注意力放在了管道的架构路径上 而把如何去架构放在了一边 我想它们是有先后关系的 并且距离并不遥远 案例描述 现在假设有两个对等点alas 和sisal 在一个局域网内 按照客户视角那一节的例程sisal先建立输入管道 alas建立输出管道 由于同一网内可以用广播的方式发送查询信息 可以不设rendevous 并且路由是两点间的 消息传递过程得到了一定的简化 案例分析 以上案例中 从输入输出管道的建立到完成对接并传输数据总共有 个步骤 sisal建立输入管道 alasl建立输出管道 需要查找输入管道 通过广播向网络发出管道查询消息 sisal获得alas的管道查询消息 通过单播向sisal发出响应表示 alas获得sisal的响应 通过单播向alas发出数据 sisal获得数据 lishixinzhi/Article/program/Java/gj/201311/27397

java如何使用管道流传递客户对象 ?

管道流可以实现两个线程之间,二进制数据的传输。

管道流就像一条管道,一端输入数据,别一端则输出数据。通常要分别用两个不同的线程来控制它们。

使用方法如下:

[html] view plaincopy

import java.io.IOException;

import java.io.PipedInputStream;

import java.io.PipedOutputStream;

public class PipedInputStreamTest {

public static void main(String[] args) {

//管道输出流

PipedOutputStream out = new PipedOutputStream();

//管道输入流

PipedInputStream in = null;

try {

//连接两个管道流。或者调用connect(Piped..);方法也可以

in = new PipedInputStream(out);

Thread read = new Thread(new Read(in));

Thread write = new Thread(new Write(out));

//启动线程

read.start();

write.start();

} catch (IOException e) {

e.printStackTrace();

}

}

}

class Write implements Runnable {

PipedOutputStream pos = null;

public Write(PipedOutputStream pos) {

this.pos = pos;

}

public void run() {

try {

System.out.println("程序将在3秒后写入数据,请稍等。。。");

Thread.sleep(3000);

pos.write("wangzhihong".getBytes());

pos.flush();

} catch (IOException e) {

e.printStackTrace();

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

try {

if (pos != null) {

pos.close();

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

class Read implements Runnable {

PipedInputStream pis = null;

public Read(PipedInputStream pis) {

this.pis = pis;

}

public void run() {

byte[] buf = new byte[1024];

try {

pis.read(buf);

System.out.println(new String(buf));

} catch (IOException e) {

e.printStackTrace();

} finally {

try {

if (pis != null) {

pis.close();

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

java 管道流

管道流实际上就是整行的读取和写入,不用每个字节每个字节的读取和写入

读写是两个不同的分支,通常都是分开单独使用的。

可以通过BufferedReader 流的形式进行流缓存,之后通过readLine方法获取到缓存的内容。

BufferedReader bre = null;

try {

String file = "D:/test/test.txt";

bre = new BufferedReader(new FileReader(file));//此时获取到的bre就是整个文件的缓存流

while ((str = bre.readLine())!= null) // 判断最后一行不存在,为空结束循环

{

System.out.println(str);//原样输出读到的内容

};

备注一: 流用完之后必须close掉,如上面的就应该是:bre.close(),否则bre流会一直存在,直到程序运行结束。

可以通过“FileOutputStream”创建文件实例,之后过“OutputStreamWriter”流的形式进行存储,举例:

OutputStreamWriter pw = null;//定义一个流

pw = new OutputStreamWriter(new FileOutputStream(“D:/test.txt”),"GBK");//确认流的输出文件和编码格式,此过程创建了“test.txt”实例

pw.write("我是要写入到记事本文件的内容");//将要写入文件的内容,可以多次write

pw.close();//关闭流

备注二:文件流用完之后必须及时通过close方法关闭,否则会一直处于打开状态,直至程序停止,增加系统负担。

Java 中利用管道实现线程间的通讯

在Java 语言中 提供了各种各样的输入输出流(stream) 使我们能够很方便的对数据进行操作 其中 管道(pipe)流是一种特殊的流 用于在不同线程(threads)间直接传送数据 一个线程发送数据到输出管道 另一个线程从输入管道中读数据 通过使用管道 实现不同线程间的通讯 无需求助于类似临时文件之类的东西 本文在简要介绍管道的基本概念后 将以一个具体的实例pipeapp加以详细说明 .管道的创建与使用Java提供了两个特殊的专门的类专门用于处理管道 它们就是pipedinputstream类和pipeoutputstream类 Pipedinputstream代表了数据在管道中的输出端 也就是线程向管道读数据的一端 pipeoutputstream代表了数据在管道中的输入端 也就是线程向管道写数据的一端 这两个类一起使用可以提供数据的管道流 为了创建一个管道流 我们必须首先创建一个pipeoutstream对象 然后 创建pipeinputstream对象 实例如下 pipeout= new pipedyoutstream();pipein= new pipedputsteam(pipepout);一旦创建了一个管道后 就可以象操作文件一样对管道进行数据的读写 .演示程序 pipeapp应用程序由三个程序组成 主线程(pipeapp Java)及由主线程启动的两个二级线程(ythread Java和zthread Java) 它们使用管道来处理数据 程序从一个内容为一行一行 x 字母的 input txt 文件中读取数据 使用管道传输数据 第一次是利用线程ythread将数据 x 转换为 y 最后利用线程zthread将 y 转换为 z 之后 程序在屏幕上显示修改后的数据 主线程 (pipeapp Java)在main()方法中 程序首先创建一个应用对象 pipeapp pipeapp=new pipeapp();由于程序中流操作都需要使用IOException异常处理 所以设置了一个try块 在try中 为了从源文件中读取数据 程序为 input txt 文件创建了一个输入流Xfileln :fileinputstream xfileln= new fileinputstream( input txt );新的输入流传递给changetoy()方法 让线程ythread能读取该文件 inputstream ylnpipe =pipeapp changetoy(xfileln);changetoy()方法创建将输入数据 x 改变到 y 的线程ythread 并返回该线程的输入管道 inputstream zlnpipe = pipeapp changetoz(ylnpipe);changetoz()方法启动将数据从 y 改变到 z 的线程zehread 主程序将使用从changetoz()返回的输入管道 得到以修改的数据 然后 程序将管道输入流定位到datainputstream对象 使程序能够使用readline()方法读取数据 datainputstream inputstream = new datainputstream(zlnpiepe);创建了输入流以后 程序就可以以行一行的读取数据病显示在屏幕上 String str= inputstream readline();While(str!=null){system out println(str); str=inputstream readline();} 显示完成之后 程序关闭输入流 inputstream close();changetoy()方法 changetoy()方法首先通过传递一个参数inputstream给datainputstream对象来定位资源的输入流 使程序能使用readline()方法从流中读取数据 datainputstream xfileln =new datainutstream(inputstream) 然后 changetoy()创建输出管道和输入管道 pipeoutstream pipeout = new pipeoutputstream();pipeinputstream pipeln = new pipedinputsteam(pipeout); 为了能够使用println()方法输出修改的后的文本行到管道 程序将输出管道定位到printstream对象 printstream printstream = new printstream(pipeout);现在 程序可以创建将数据从x改变到y的线程 该线程是ythread类的一个对象 他传递两个参数 输入文件(xfileln)和输出管道(调用printstream) ythread ythread =new thread(xfileln printstream);之后 程序启动线程 changetoz()方法changetoz()方法与changetoy()方法很相似 他从changetoy()返回的输入流开始 datainputstream yfileln= new datainputstream(inputstream);程序创建一个新的管道 pipedoutstream pipeout = new pipedoutputstream();pipedinputstream pipeln = new pipedinputsream(pipeout ); 该线程通过这个新的管道发出修改后的数据(输入流pipeln )给主程序 源程序如下 ////pipeapp Java pipeapp的主应用程序//import Java io *class pipeapp{public static void main(string[] args){pipeapp pipeapp=new pipeapp();try{fileinputstream xfile =new fileinputstream( input txt );inputstream ylnpipe = pipeapp changetoy(xfileln);inputstream zlnpipe=pipeapp changetoz(ylnpipe);system out println();system out println( here are the results );system out pringln();datainputstream inputstream = nes datainputstream(zlnpipe);string str = inputstream readline();while (str!=null){system out println(str);str=inputstream readline();}inputstream close();}catch(exception e){system out println(e tostring());}}public inputstream changetoy(inputstream inputstream){try{datainputstream pipeout = new datainputsteam(inputstream);pipedoutstream pipeout = new pipedoutputstream();pipedlnsteam pipeln = new pipedlnputstream(pipeout);printstream printstream = new printstream(pipeout);ythread ythread = new ythread(xfileln printstream);ythread start();return pipeln;}catch(exeption e){system out println(x tostring());}return null;}public inputstream changetoz(inputstream inputsteam){try{datainputstream yfileln = new datainputstream(inputstream);pipeoutputstream pipeln = new pipedinputstream(pipeout );printrstream printstream = new printsteam(pipeout );zthread zthread = new zthread(yfileln printstream );zthread start();return pipeln ;}catch(exception e){system out println(e tostring());}return null;}} Ythread类和Zthread类由于ythread类与zthread类基本一样 在此仅以ythread为例加以说明 Ythread的构造器接收两个参数 输入的文件和第一个管道的输出端 构造器存储这两个参数作为类的数据成员  Ythread(datainputstream xfileln pringstream printstream){this xfileln = xfileln;this printstream = printstream;} 线程通过run()方法来处理数据 首先读取一行数据 确保xstring不为空的情况下循环执行 string xstring = xfileln readline();每读一行数据 完成一次转换string ystring = xstring replace( x y );然后将修改后的数据输出到管道的输出端 prinstream prinrln(ystring);为了确保所有缓冲区的数据完全进入管道的输出端 pringstram flush();循环完成后 线程关闭管道输出流  pringstram close();ythread类的源程序如下 //ythread Java//import Java io *;class ythread exteads thread{datainputstream xfileln;pringstream printstream;ythread(datainputstream xfileln pringstream printstream){this xfileln = xfileln;this printstream = printstream;}public void run(){try{string xstring = xfileln readline();while(xstring!=null){string ystring= xstring replace( x y );printstream pringln(ystring);printstream flush();xstring= xfileln readline();}printstream close();}catch{ioexception e}{system out println(e tostring());}}} pipeapp应用程序使用microsoft visual j++ 编译 lishixinzhi/Article/program/Java/gj/201311/27508

管道实现java的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于管道的实现、管道实现java的信息别忘了在本站进行查找喔。