我需要从Java访问编号文件描述符--而不是0、1或2。
如何做到这一点?我查看了FileDescriptor类,但没有找到任何方法来使用给定的文件描述符号对其进行初始化。
作为一个具体的例子,让我们假设Java被另一种编程语言作为子进程调用。文件描述符3和4由另一种语言提供用于输入和输出。
在Java语言中,我需要的是连接到这些文件描述符的InputStream和OutputStream对象,就像System.in、System.out和System.error连接到文件描述符0、1和2一样。
我使用的是Java 1.6,应该可以在类似Unix的系统上运行。
发布于 2011-01-31 04:04:18
我确信这不能用纯Java语言实现--您可能必须使用本机代码将文件描述符绑定到FileDescriptor对象、FileInputStream或FileOutputStream对象。
编辑
如果您使用的是Linux、*BSD或macOS,那么可以使用伪文件/dev/fd/nnn来访问文件描述符nnn。
发布于 2012-04-10 21:57:31
使用SUN JavaVM,您可以执行以下操作:
FileDescriptor fd = new FileDescriptor();
sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess().set(fd,3);
FileInputStream fin = new FileInputStream(fd);发布于 2016-04-25 07:18:54
我最近需要为监狱中运行的Java子进程执行此操作。这意味着它不能访问/dev/fd文件系统。
@Bozho发表了一条评论,认为反射可能会也可能不会创建FileDescriptor对象。不过,在我做的一个简单的测试中,它似乎是有效的。以下是TestFD.java的源代码:
import java.lang.reflect.Constructor;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
public class TestFD {
public static void main(String[] args) throws Exception {
Constructor<FileDescriptor> ctor = FileDescriptor.class.getDeclaredConstructor(Integer.TYPE);
ctor.setAccessible(true);
FileDescriptor fd = ctor.newInstance(3);
ctor.setAccessible(false);
new FileOutputStream(fd).write("hi there\n".getBytes());
}
}为了测试这一点,我创建了一个简单的Bash脚本来编译它,设置fd3,并运行java程序:
#!/bin/bash
javac TestFD.java
exec 3>&1 # open fd3, redirect to stdout
java TestFD
exec 3>&-果然,fd3被重定向到stdout,并在终端上输出"hi there\n“。注释掉"exec 3>&1“行,Java程序会像预期的那样失败,并显示"Device not configured”IOException。
在私有FileDescriptor构造函数上的反射在不可能访问/dev/fd的情况下似乎工作得很好,并且比尝试使用JNI创建FileDescriptor要简单一些,我在其他地方也看到过这种建议。
注意:我在BSD系统上对此进行了测试。它可能在其他系统上工作,也可能不工作。
https://stackoverflow.com/questions/4845122
复制相似问题