3

我有一些代码可以使用FileOutputStream. 这是我写了一千遍的标准代码:

FileOutputStream out = new FileOutputStream(file);
try {
    BufferedOutputStream bos = new BufferedOutputStream(out);
    try {
        store(bos, comments);
    } finally {
        bos.close();
    }
} finally {
    out.close();
}

close()我们的一位用户在通话期间在 Linux 上报告了以下错误。

java.io.IOException: Inappropriate ioctl for device
   at java.io.FileOutputStream.close0(Native Method)
   at java.io.FileOutputStream.close(FileOutputStream.java:341)
   at java.io.FilterOutputStream.close(FilterOutputStream.java:160)

有谁知道这是否仅在使用错误的 -d32 或 -d64 参数错误地启动 JVM 时发生(如在这个问题中),还是可能发生其他事情?

4

2 回答 2

2

我很确定您对 32/64 位模式的想法是正确的。几年前我们在嵌入式设备上遇到过这个问题,错误源于我们用来与 pci 开关通信的库,并且该库不支持 64 位 ioctls。

如果您真的想深入了解它,我的建议是我已经使用这种技术来调试 jni 代码。在 java 应用程序中设置断点,然后使用 gdb 附加到进程。然后,您可以在 gdb 中设置断点以监视设备上的 ioctl。查看正在向设备发送哪个请求,并验证它是否正确支持该架构。

如果文件输出流是从文件系统文件而不是其他类型的设备文件中读取的。那么这可能是 selinux 或某种虚拟化(如 chroot 环境)的问题,如下面的链接所示。

此链接可能指向正确的方向。这是 chroot 的问题
http://us.generation-nt.com/answer/sndctl-tmr-timebase-tcgets-help-170073041.html

还要检查他们正在运行的 jre,是 openjdk 还是 sun java?我对旧的 gcc jdk java 有一些非常奇怪的怪癖,这可以解释一些差异。

于 2013-02-23T22:31:49.673 回答
1

Java 的方法是对操作系统本机 close()close()的薄包装;它将本机错误代码转换为异常。

链接到的文档对于可能导致关闭失败的原因相对模棱两可,并指出写入期间的错误可能会由关闭报告,并且“这尤其可以通过 NFS 观察到......”。

因此,为了调试,我首先要查看文件的名称,以及为这个特定用户存储文件的位置。对于“不适当的 ioctl”,我不会过多强调与非 close() 相关的命中。

于 2013-02-12T20:10:44.727 回答