软件体系结构实验一
1.在Dos命令下分别使用 dir 命令和dir|more 命令,体验管道过滤模型
dir
显示当前工作目录下的子目录和文件more
每次显示一个输出屏幕dir | more
以每次显示一个输出屏幕的方式显示当前工作目录下的子目录和文件
这里的 | 是就是管道,将第一个命令的输出作为输入,用第二个命令去处理。
为什么要用管道
- 管道是进程间通信的方式之一,每一条命令都是一个程序
- 命令的与发紧凑并且简单
- 使用管道,将多个命令串连到一起,有时候可以完成命令单独执行不方便或者不能完成的复杂任务
- 从管道输出的标准错误会混合到一起
过滤器
将几个命令通过管道符组合在一起就形成了管道。通常,通过这种方式使用的命令就被称为过滤器。过滤器会获取输入,通过某种方式修改其内容,然后将其输出。
dir
命令
C:\Users\Liuhd>dir
驱动器 C 中的卷是 Windows-SSD
卷的序列号是 4009-8282
C:\Users\Liuhd 的目录
2021/10/10 13:44 <DIR> .
2021/08/16 13:37 <DIR> ..
2021/10/06 22:31 <DIR> .android
2021/09/25 11:32 340 .bash_history
2021/04/12 20:51 <DIR> .cache
2021/09/24 17:03 <DIR> .config
2021/04/12 20:51 <DIR> .eclipse
2021/10/01 12:08 16 .emulator_console_auth_token
2021/09/24 17:37 81 .gitconfig
2021/10/01 11:40 <DIR> .gradle
2021/09/24 17:03 <DIR> .halo
2021/09/29 16:10 <DIR> .jdks
2021/04/06 11:08 1,907 .labelmerc
2021/09/29 16:02 <DIR> .m2
2021/04/06 11:08 <DIR> .matplotlib
2021/10/10 13:44 <DIR> .mume
2021/04/06 11:07 12 .python_history
2021/03/29 20:59 <DIR> .ssh
2021/09/27 20:49 3,362 .viminfo
2021/03/23 20:31 <DIR> .vscode
2021/03/23 16:46 <DIR> 3D Objects
2021/04/06 11:02 <DIR> anaconda3
2021/10/01 11:24 <DIR> AndroidProject
2021/09/02 10:35 <DIR> CLionProjects
2021/08/16 17:40 <DIR> Contacts
2021/09/03 22:43 300 d4ac4633ebd6440fa397b84f1bc94a3c.7z
2021/10/11 12:22 <DIR> Desktop
2021/10/06 16:51 <DIR> Documents
2021/10/10 13:36 <DIR> Downloads
2021/04/12 20:51 <DIR> eclipse-workspace
2021/08/16 17:40 <DIR> Favorites
2021/10/06 17:05 <DIR> IdeaProjects
2021/08/29 20:19 0 import_sys.SQL
2021/09/03 22:09 66 inittk.ini
2021/09/03 22:09 41 inst.ini
2021/08/16 17:40 <DIR> Links
2021/08/16 17:40 <DIR> Music
2021/09/03 22:09 <DIR> Nox_share
2021/09/03 22:09 45 nuuid.ini
2021/10/11 14:01 <DIR> OneDrive
2021/08/29 18:09 <DIR> Oracle
2021/09/05 19:41 <DIR> Pictures
2021/04/26 13:24 <DIR> PotPlayer
2021/08/16 17:40 <DIR> Saved Games
2021/08/16 17:40 <DIR> Searches
2021/03/23 17:06 <DIR> UIDowner
2021/09/03 22:09 53 useruid.ini
2021/08/16 17:40 <DIR> Videos
2021/09/03 22:08 <DIR> vmlogs
12 个文件 6,223 字节
37 个目录 119,086,456,832 可用字节
dir|more
命令
C:\Users\Liuhd 的目录
2021/10/10 13:44 <DIR> .
2021/08/16 13:37 <DIR> ..
2021/10/06 22:31 <DIR> .android
2021/09/25 11:32 340 .bash_history
2021/04/12 20:51 <DIR> .cache
2021/09/24 17:03 <DIR> .config
2021/04/12 20:51 <DIR> .eclipse
2021/10/01 12:08 16 .emulator_console_auth_token
2021/09/24 17:37 81 .gitconfig
2021/10/01 11:40 <DIR> .gradle
2021/09/24 17:03 <DIR> .halo
2021/09/29 16:10 <DIR> .jdks
2021/04/06 11:08 1,907 .labelmerc
2021/09/29 16:02 <DIR> .m2
2021/04/06 11:08 <DIR> .matplotlib
2021/10/10 13:44 <DIR> .mume
2021/04/06 11:07 12 .python_history
2021/03/29 20:59 <DIR> .ssh
2021/09/27 20:49 3,362 .viminfo
2021/03/23 20:31 <DIR> .vscode
2021/03/23 16:46 <DIR> 3D Objects
2021/04/06 11:02 <DIR> anaconda3
2021/10/01 11:24 <DIR> AndroidProject
2021/09/02 10:35 <DIR> CLionProjects
2021/08/16 17:40 <DIR> Contacts
2021/09/03 22:43 300 d4ac4633ebd6440fa397b84f1bc94a3c.7z
2021/10/11 12:22 <DIR> Desktop
2021/10/06 16:51 <DIR> Documents
2021/10/10 13:36 <DIR> Downloads
2021/04/12 20:51 <DIR> eclipse-workspace
2021/08/16 17:40 <DIR> Favorites
2021/10/06 17:05 <DIR> IdeaProjects
2021/08/29 20:19 0 import_sys.SQL
2021/09/03 22:09 66 inittk.ini
2021/09/03 22:09 41 inst.ini
2021/08/16 17:40 <DIR> Links
2021/08/16 17:40 <DIR> Music
2021/09/03 22:09 <DIR> Nox_share
2021/09/03 22:09 45 nuuid.ini
2021/10/11 14:01 <DIR> OneDrive
2021/08/29 18:09 <DIR> Oracle
2021/09/05 19:41 <DIR> Pictures
2021/04/26 13:24 <DIR> PotPlayer
-- More --
2.使用Java的管道流类实现管道-过滤体系结构,完成客户端发送一段文字,接收端进行接收,利用线程实现这一功能。
java的管道输入与输出实际上使用的是一个循环缓冲数组来实现,这个数组默认大小为1024字节。输入流PipedInputStream从这个循环缓冲数组中读数据,输出流PipedOutputStream往这个循环缓冲数组中写入数据。当这个缓冲数组已满的时候,输出流PipedOutputStream所在的线程将阻塞;当这个缓冲数组首次为空的时候,输入流PipedInputStream所在的线程将阻塞。但是在实际用起来的时候,却会发现并不是那么好用。
pipedInputStream.connect(pipedOutputStream)
或者pipedOutputStream.connect(pipedInputStream)
效果是一样的
只能选择其中的一个,不能两个connect同时调用
在一个线程里使用PipedInpuStream
和PipedOutputStream
会造成死锁,第二次尝试通过管道输出流写数据的时候阻塞,同时也无法从管道输入流读取数据,感兴趣的同学可以点进这两个类中查看read()
和write()
这两个方法的源码,这两个都是同步方法。
所以我设计了一个发送端class Sender
和一个接收端class Receiver
作为管道的两端,在主线程中进行数据的发送,在另一个接收线程中进行数据的接收
这样就可以避免线程,这里要特别注意发送和接收的同步关系
public class PipedDemo{
public static void main(String[] args) {
Receiver receiver = new Receiver();
Sender sender = new Sender(receiver);
sender.send();
new Thread(receiver).start();
}