- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个与 PipedInputStream
相关的问题和 PipedOutputStream
,也不知道是我对这些类的设计有误解,还是PipedInputStream.java
中的java代码有bug
据我了解PipedInputStream
和 PipedOutputStream
实现一种可用于在两个不同线程之间创建流的机制。生产者线程在 PipedOutputStream
中写入了一些内容。消费者线程在连接的 PipedInputStream
中读取它.有一个内部缓冲区以允许缓冲通信。默认情况下,此缓冲区的大小为 1024 字节。
如果消费者线程读取 PipedInputStream
并且缓冲区为空,然后线程等待。如果生产者线程写入 PipedOutputStream
并且缓冲区已满,然后线程也等待。PipedInputStream
维护内部缓冲区,PipedOutputStream
只使用 PipedInputStream
中声明的函数.PipedInputStream
中与内部(循环)缓冲区相关的所有字段( byte [] buffer
、 int in
和 int out
-正如您在 PipedInputStream.java
中看到的那样)都声明为 protected
. PipedInputStream
使用 2 个不同的 PipedInputStream.receive
注入(inject)数据职能。
所有 InputStreams 都有两个读取版本:read()
和 read(byte [], int, int)
.所有的 OutputStreams 都有两个写入版本 write(byte b)
和 write(byte [], int, int)
.都有一个单字节版本和一个多字节版本。 PipedInputStream
和 PipedOutputStream
有这些功能。PipedOutputStream.write(byte b)
使用 PipedInputStream.receive(int b)
在连接的PipedInputStream
中注入(inject)字节的函数.此接收函数声明为 protected
所以你可以重载这个函数并拦截来自PipedOutputStream
的任何字节注入(inject)连接到PipedInputStream
.PipedOutputStream.write(byte b[], int offset, int len)
使用 PipedInputStream.receive(byte [] b, int offset, int len)
在连接的 PipedInputStream
中注入(inject)一个字节数组.
我的问题来了:PipedInputStream.receive(byte [], int, int)
, receive(int)
的多字节对应物, 未被声明为 receive(int)
也就是说,它具有默认的可见性(包可见性)。所以你不能重载这个函数并拦截来自 PipedOutputStream
的多字节注入(inject)。连接到PipedInputStream
.PipedInputStream.write(byte b[], int offset, int len)
不调用 PipedInputStream.write(int b)
.所以重载receive(int)
使用 receive(byte [],int, int)
时无效.
据我了解,PipedInputStream.receive(byte[], int, int)
应该是 protected
如PipedInputStream.receive(int)
是。它的声明:synchronized void receive(byte [] b, int off, int len) throws IOException {
应该:protected synchronized void receive(byte [] b, int off, int len) throws IOException {
PipeReader
和 PipeWriter
(PipedInputStream
和 PipedOutputStream
的字符版本)声明缓冲区字段和具有包可见性的接收方法(不 protected !)。 Java 中的 Reader/Writer(JDK1.1 起)比 InputStream/OutputStream(JDK1.0 起)更新。PipedInputStream
的设计中是否存在真正的错误? ?, 是 protected
PipedInputStream
中的可见度从早期 Java 版本继承的设计事故?还是我完全迷失了?
提前致谢。
PD:这是出现此问题的示例。该程序无法编译(由提到的接收可见性问题)。在这个例子中,我尝试创建一个 PipedInputStream
允许在需要时自动扩展缓冲区的子类。因此,如果缓冲区为空并且有人尝试读取线程等待。但是,如果缓冲区已满并且有人尝试写入(使用连接的 PipedOutputStream
),则线程不会等待,而是扩展缓冲区以存储更多字节。消费者等待,但生产者不等待。
我有自己的这个例子的功能实现,但我想知道它是否不能实现为 PipedInputStream
子类。
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class ExtensiblePipedInputStream extends PipedInputStream {
/**
* Default extensions' size
*/
private static final int DEFAULT_EXTENSION = 1024;
/**
* The current extensions' size
*/
protected int extension = DEFAULT_EXTENSION;
// the same constructors than the super class (PipedInputStream)...
public ExtensiblePipedInputStream() {
super();
}
public ExtensiblePipedInputStream(PipedOutputStream src) throws IOException {
super(src);
}
public ExtensiblePipedInputStream(int pipeSize) {
super(pipeSize);
}
public ExtensiblePipedInputStream(PipedOutputStream src, int pipeSize) throws IOException {
super(src, pipeSize);
}
/**
* This function ensures the specified capacity in the internal buffer. If
* the specified capacity is less or equals than the current internal buffer
* capacity it does nothing. If the specified capacity is greater than the
* current one, then the buffer is extended to: at least allocate the new
* capacity. This function extends the buffer using multiple factors of
* extension size.
*
* @param capacity The capacity
* @throws IOException if an IO error occurs
* @throws IllegalArgumentException if capacity is negative
*/
public synchronized void ensureCapacity(int capacity) throws IOException, IllegalArgumentException {
if (capacity < 0) {
throw new IllegalArgumentException("capacity < 0");
}
if (capacity > buffer.length) {
int additionalSpace = capacity - buffer.length;
final int modExtension = additionalSpace % extension;
additionalSpace += (modExtension == 0) ? 0 : extension - modExtension;
setCapacity(buffer.length + additionalSpace);
}
}
/**
* Returns capacity of the internal buffer (the buffer's size).
*
* @return The capacity or the internal buffer
*/
public synchronized int getCapacity() {
return buffer.length;
}
/**
* Returns the size of the next buffer's extensions.
*
* @return The size of the next buffer's extensions.
*/
public synchronized int getExtension() {
return extension;
}
/**
* This function extends and invokes PipedInputStream.receive. It only avoid
* writers block by extending the internal buffer when needed.
*
* @param b The byte to be received
* @throws IOException if an IO error occurs
*/
@Override
protected synchronized void receive(int b) throws IOException {
ensureCapacity(available() + 1);
super.receive(b);
}
/**
* MY PROBLEM!!!!
*
* this function is not posible!
*
* PipedInputStream.receive(byte[], int, int)
* has not protected visibility, it has package visibility!!!!!
*
* Why?
*
* @param b The array of bytes to be received
* @param off The offset in the array of bytes.
* @param len The number of bytes to be received.
* @throws IOException If an IO error occurs
*/
@Override
protected synchronized void receive(byte b[], int off, int len) throws IOException {
ensureCapacity(available() + len);
super.receive(b, off, len);
}
/**
* Changes the size of the internal buffer. The new size must be greater or
* equals than the number of bytes stored in the internal buffer
* (available())
*
* @param capacity The new size of the internal buffer.
* @throws IOException If an IO error occurs.
* @throws IllegalArgumentException If capacity < available()
*/
public synchronized void setCapacity(int capacity) throws IOException, IllegalArgumentException {
final int available = available();
if (capacity < available) {
throw new IllegalArgumentException("capacity < available");
}
final byte[] nbuf = new byte[capacity];
if (available > 0) {
final int firstTransferAmount = Math.min(available, buffer.length - out);
System.arraycopy(buffer, out, nbuf, 0, firstTransferAmount);
if (in > 0) {
System.arraycopy(buffer, 0, nbuf, firstTransferAmount, in);
}
out = 0;
in = (available == capacity) ? 0 : available;
}
buffer = nbuf;
}
/**
* Set the size of future extensions. It must be a value greater than 0.
*
* @param extension The size of future extensions.
* @throws IllegalArgumentException If extension <= 0
*/
public synchronized void setExtension(int extension) throws IllegalArgumentException {
if (extension <= 0) {
throw new IllegalArgumentException("extension <= 0");
}
this.extension = extension;
}
}
最佳答案
我认为您误解了管道的用途。管道用于 阻塞 两个不同线程之间的通信。写入器的速度预计将受限于读取器的速度,这意味着管道在内存使用方面是有效的,但会将处理限制为最慢组件的速度。
如果您想要异步写入,您应该考虑使用 Queue - java.util.concurrent 包中的版本之一应该适合。
关于java - PipedInputStream.java 的设计中是否存在错误或者我误解了它的设计?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28364621/
我有一个与 PipedInputStream 相关的问题和 PipedOutputStream ,也不知道是我对这些类的设计有误解,还是PipedInputStream.java中的java代码有bu
我正在使用java管道将数据(outstream)从解压模块(JavaUncompress类)传递到解析模块(处理类),文件很大,我想先解压文件并直接解析而不是保存解压缩的文件,然后解析。但是,它仅适
我正在学习 java PipedInputStream/PipeOutputStream 。 我想读取标准输入(下面的“Source”类)并将其重定向到一个进程(此处为“grep A”),Grep 的
我在 SO 上看到了两个答案,它们声称 Java 提供的 PipedInputStream 和 PipedOutputStream 类存在缺陷。但他们没有详细说明他们出了什么问题。他们真的有缺陷吗?如
我正在尝试编写一段解锁代码来读取 PipedInputStream .它基本上会在调用阻塞读取 API 之前检查是否有任何内容要读取: int n = 0; if ((n = pipedInputSt
PipedInputStream 如何从 PipedOutputStream 读取数据?是使用toString()还是有一些隐藏的魔法来访问private成员变量? 最佳答案 PipedOutputS
我正在编写一个程序,该程序通过使用 Class 和 Method 类调用 main 方法来执行另一个 Java 程序。然后,另一个程序尝试从 System.in 读取。为了将参数传递给程序,我将 Sy
什么是管道流的用例?为什么不将数据读入缓冲区然后将它们写出呢? 最佳答案 BlockingQueue 或类似的集合可能会更好地为您服务,它们是线程安全的、健壮的并且扩展性更好。 关于java - Pi
Write end dead exception在以下情况发生:两个线程: A: PipedOutputStream put = new PipedOutputStream(); String
我正在编写一个简单的 Swing GUI,其中包含一个用于打印调试消息和异常的文本字段。我目前在写入 PipedOutputStream 的地方设置了它,并且我有一个守护线程,它从连接的 PipedI
我有一个需要读取的 OutputStream,因此我使用以下 (Groovy) 代码来获取对数据的 InputStream 引用: PipedInputStream inputStream = new
我有一个数据生成器,它在单独的线程中运行并将生成的数据推送到连接到 PipedInputStream 的 PipedOutputStream 中。此输入流的引用通过公共(public) API 公开,
PipedOutputStream的Android实现 write(byte[] buffer, int offset, int count) 是根据write(byte oneByte)实现的。更具
我有一个具有单读者线程模型的多写入线程。ThreadMultipleDateReceiver 类设计用于从多个线程读取。 public class ThreadMultipleDateReceiver
我在 Scala 中有以下代码: val pos = new PipedOutputStream() val pis = new PipedInputStream(pos)
如何正确完成管道输出端的工作?我需要写入线程终止或做一些其他工作,而读取线程读取所有写入数据直到结束。 我应该在写入端关闭管道还是什么? 更新 1 我想澄清一下......根据给定的答案,我认为设计管
我想使用 PipedOutputStream 和 PipedInputStream Java 类编写类似于Producer Consumer Problem 的示例。 注意:这是应用其原理的小示例。
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭10
我不确定,但我很确定我在 Oracle Java 实现(1.7.0_67 和 1.8.0_31 我可以确认受影响)中发现了一个错误(或未记录的功能)。 症状 当管道已满时,写入管道的时间可能比管道再次
我最近发现了这个成语,我想知道我是否遗漏了什么。我从未见过它使用过。我在野外使用过的几乎所有 Java 代码都倾向于将数据放入字符串或缓冲区中,而不是像这个示例(例如使用 HttpClient 和 X
我是一名优秀的程序员,十分优秀!