gpt4 book ai didi

java - 什么会导致 close(2) 因只读文件的 EIO 而失败?

转载 作者:太空狗 更新时间:2023-10-29 13:28:32 24 4
gpt4 key购买 nike

我正在调查 Android 上的一个问题,其中由于未能关闭文件而引发 IOException:

java.io.IOException: close failed: EIO (I/O error)
at libcore.io.IoUtils.close(IoUtils.java:41)
at java.io.FileInputStream.close(FileInputStream.java:121)
at com.adamrosenfield.wordswithcrosses.io.JPZIO.convertJPZPuzzle(JPZIO.java:191)
at com.adamrosenfield.wordswithcrosses.net.AbstractJPZDownloader.download(AbstractJPZDownloader.java:56)
at com.adamrosenfield.wordswithcrosses.net.AbstractJPZDownloader.download(AbstractJPZDownloader.java:41)
at com.adamrosenfield.wordswithcrosses.net.AbstractDownloader.download(AbstractDownloader.java:112)
at com.adamrosenfield.wordswithcrosses.net.AbstractDownloader.download(AbstractDownloader.java:108)
at com.adamrosenfield.wordswithcrosses.net.Downloaders.download(Downloaders.java:257)
at com.adamrosenfield.wordswithcrosses.BrowseActivity.internalDownload(BrowseActivity.java:702)
at com.adamrosenfield.wordswithcrosses.BrowseActivity.access$6(BrowseActivity.java:696)
at com.adamrosenfield.wordswithcrosses.BrowseActivity$7.run(BrowseActivity.java:691)
at java.lang.Thread.run(Thread.java:856)
Caused by: libcore.io.ErrnoException: close failed: EIO (I/O error)
at libcore.io.Posix.close(Native Method)
at libcore.io.BlockGuardOs.close(BlockGuardOs.java:75)
at libcore.io.IoUtils.close(IoUtils.java:38)
... 11 more

相关代码:

public static void convertJPZPuzzle(File jpzFile, File destFile,
PuzzleMetadataSetter metadataSetter) throws IOException {
FileInputStream fis = new FileInputStream(jpzFile);
try {
DataOutputStream dos = new DataOutputStream(new FileOutputStream(destFile));
try {
if (!convertJPZPuzzle(fis, dos, metadataSetter)) {
throw new IOException("Failed to convert JPZ file: " + jpzFile);
}
} finally {
dos.close();
}
} finally {
fis.close();
}
}

完整来源是on GitHub .

异常是从 fis.close() 行抛出的。从我阅读 Android 源代码可以看出,FileInputStream.close() 只是向下调用了 close(2)。在 native 代码中的底层文件描述符上。

手册页似乎没有具体说明什么会导致 EIO 错误,他们只是说“发生 I/O 错误”之类的内容。或“如果在 close() 期间读取或写入文件系统时发生 I/O 错误”。 Mac OS X 手册页说它可能在“以前未提交的写入 (2) 遇到输入/输出错误”时发生。在这些系统上。

究竟是什么导致 close(2) 因文件描述符错误 EIO 而失败,该文件描述符仅为读取而打开,如本例所示?显然,这不是未提交的 write(2)。对于这个特定文件,它是使用 Android 的 DownloadManager 服务下载的,这意味着可能有延迟线程和/或进程试图同时访问它,但我几乎看不出这会对尝试关闭它有何影响。此外,此代码运行后文件将被删除 ( here ),但除非 Android 中有未记录的时间机器,否则 future 的代码不应影响此处。

我对 Android 和/或 Linux 上的答案特别感兴趣,但对于其他操作系统的更一般的答案也将不胜感激。

最佳答案

我猜 EIO 来自 fs/bad_inode.c 中的 bad_file_flush。似乎当内核访问 inode 出现任何故障时,它会将打开的文件描述转换为伪打开文件,其中 bad_inode_ops 作为其文件操作。我找不到为基于 FAT 的文件系统执行此操作的代码,但也许有一些通用代码。

至于原因,可能是连接USB线并从连接的计算机挂载文件系统,移除SD卡等。

关于java - 什么会导致 close(2) 因只读文件的 EIO 而失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18708596/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com