Java 在不关闭的情况下使流无效
这是一个后续行动 根据我前面的问题,我不能依赖这样的代码(目前碰巧在JDK8中工作): 但是,为了防止意外错误,并且作为一种自我文档的形式,我希望在使用完每个文件流后使其无效,而不关闭底层文件描述符 每个FileInputStream都是独立的,其定位由RandomAccessFile控制。我共享相同的FileDescriptor,以防止多次打开同一路径时出现任何争用情况。当我处理完一个FileInputStream后,我想使它失效,以便在使用第二个FileInputStream时不可能意外地从中读取数据(这会导致第二个FileInputStream跳过数据) 我该怎么做 注:Java 在不关闭的情况下使流无效,java,file-io,file-descriptor,fileinputstream,finalizer,Java,File Io,File Descriptor,Fileinputstream,Finalizer,这是一个后续行动 根据我前面的问题,我不能依赖这样的代码(目前碰巧在JDK8中工作): 但是,为了防止意外错误,并且作为一种自我文档的形式,我希望在使用完每个文件流后使其无效,而不关闭底层文件描述符 每个FileInputStream都是独立的,其定位由RandomAccessFile控制。我共享相同的FileDescriptor,以防止多次打开同一路径时出现任何争用情况。当我处理完一个FileInputStream后,我想使它失效,以便在使用第二个FileInputStream时不可能意外地从
- 我使用的库需要与java.io兼容*
- 如果您建议使用一个库(如果可能的话,我更喜欢内置java语义),它必须是linux(主要目标)的通用库(打包库)和windows(实验目标库)的可用库
- 但是,windows支持并不是绝对必需的
在unix下,通常可以通过使用文件描述符来避免此类问题
因为java不提供这样的特性,所以一个选项是一个本机库,它公开了这个特性。举个例子。另一方面,jnr依赖的jdk实现属性比您最初的问题多得多。纯Java解决方案可能是创建一个转发装饰器,用于检查每个方法调用是否验证流。对于
InputStream
,此装饰程序可能如下所示:
public final class CheckedInputStream extends InputStream {
final InputStream delegate;
boolean validated;
public CheckedInputStream(InputStream stream) throws FileNotFoundException {
delegate = stream;
validated = true;
}
public void invalidate() {
validated = false;
}
void checkValidated() {
if (!validated) {
throw new IllegalStateException("Stream is invalidated.");
}
}
@Override
public int read() throws IOException {
checkValidated();
return delegate.read();
}
@Override
public int read(byte b[]) throws IOException {
checkValidated();
return read(b, 0, b.length);
}
@Override
public int read(byte b[], int off, int len) throws IOException {
checkValidated();
return delegate.read(b, off, len);
}
@Override
public long skip(long n) throws IOException {
checkValidated();
return delegate.skip(n);
}
@Override
public int available() throws IOException {
checkValidated();
return delegate.available();
}
@Override
public void close() throws IOException {
checkValidated();
delegate.close();
}
@Override
public synchronized void mark(int readlimit) {
checkValidated();
delegate.mark(readlimit);
}
@Override
public synchronized void reset() throws IOException {
checkValidated();
delegate.reset();
}
@Override
public boolean markSupported() {
checkValidated();
return delegate.markSupported();
}
}
您可以像这样使用它:
CheckedInputStream f_1 = new CheckedInputStream(new FileInputStream(r.getFD()));
// some io, not shown
f_1.invalidate();
f_1.read(); // throws IllegalStateException
如果您解释需要在同一个FD上打开不同流的原因,可能会有所帮助。我假设您希望按顺序多次读取文件,但为什么不使用适当的争用控制共享
RandomAccessFile
?这有一种代码的味道,或者可能是一种错误。我的目标是提供实验性windows构建的软件。我更新了我的问题以反映这一点。这非常好-您的CheckedInputStream类保护我不受从传入流中读取的库方法的影响。所以,如果我从流1创建流2,将流2传递给库1,求0,从流1读取,并调用库1函数(我不知道从流2读取),从流1读取的第二次数据将跳过数据。CheckedInputClass保护我不受此影响。只有两个问题:CheckedInputClass是否可以通过编程而不是手动定义?如果这是python,我将重写uuu getattribute,使用元类或类装饰器。苹果和橘子我知道,但java确实有一些反射能力。第二:为什么字节码编译器没有警告我没有捕获CheckedInputStream抛出的IllegalStateException(即,您的示例,没有try/catch)?1。我认为Java中没有一种简单的方法可以生成这样一个类。对于大多数集合类,Guava提供了转发装饰器(例如),但是对于您的用例,您仍然需要覆盖每个方法,这样对您没有帮助。2.IllegalStateException是一个RuntimeException,因此是一个。
public final class CheckedInputStream extends InputStream {
final InputStream delegate;
boolean validated;
public CheckedInputStream(InputStream stream) throws FileNotFoundException {
delegate = stream;
validated = true;
}
public void invalidate() {
validated = false;
}
void checkValidated() {
if (!validated) {
throw new IllegalStateException("Stream is invalidated.");
}
}
@Override
public int read() throws IOException {
checkValidated();
return delegate.read();
}
@Override
public int read(byte b[]) throws IOException {
checkValidated();
return read(b, 0, b.length);
}
@Override
public int read(byte b[], int off, int len) throws IOException {
checkValidated();
return delegate.read(b, off, len);
}
@Override
public long skip(long n) throws IOException {
checkValidated();
return delegate.skip(n);
}
@Override
public int available() throws IOException {
checkValidated();
return delegate.available();
}
@Override
public void close() throws IOException {
checkValidated();
delegate.close();
}
@Override
public synchronized void mark(int readlimit) {
checkValidated();
delegate.mark(readlimit);
}
@Override
public synchronized void reset() throws IOException {
checkValidated();
delegate.reset();
}
@Override
public boolean markSupported() {
checkValidated();
return delegate.markSupported();
}
}
CheckedInputStream f_1 = new CheckedInputStream(new FileInputStream(r.getFD()));
// some io, not shown
f_1.invalidate();
f_1.read(); // throws IllegalStateException