【发布时间】:2022-11-14 07:02:08
【问题描述】:
Mac OSx(Macbook Pro M1、Monterey 12.3)上的 Java(8 和 17)将外部 USB 驱动器视为不可读。这曾经有效,相信问题是从安装 12.3 开始的。下面的测试例程显示 File(..).canRead() 和 Files.isReadable(..) 都返回 false。所有其他应用程序(Finder、终端、Time Machine)都使用相同的驱动器,没有任何问题。提交给 Apple 的问题报告,但有其他人看到过这个问题吗?
注意:如果驱动器不可读,则 File(..).listFiles() 返回 NULL 并且 Files.list(..) 引发异常。
import java.nio.file.*;
import java.io.*;
/** Test routine for failure to access external USB drive (USBExtA in testPath) from Java.
*
* The testPath is attempting to access Time Machine backups on the external drive, which shows as not readable in Java.
* BUT IT IS READABLE with no problems from Finder, the terminal, and other applications. Time Machine is still
* successfully writing backups to this drive.
*
* THIS USED TO WORK -- believe that it stopped working with installation of Monterey 12.3, and took a while
* before I noticed the problem (but not exactly sure of the date when 12.3 installed).
*
* ----------- Output of executions using Java 8 and Java 17 ------------------
*
* --------- Execution Context ----------
* java.version -- 1.8.0_311
* java.vendor -- Oracle Corporation
* java.vm.version -- 25.311-b11
* java.vm.vendor -- Oracle Corporation
* java.class.version -- 52.0
* os.name -- Mac OS X
* os.arch -- x86_64
* os.version -- 10.16
*
* java.io.File -- Exists: T , Readable: T , Dir: T , java.nio.Files -- Exists: T , Readable: T , Dir: T --- PATH: /Volumes
* java.io.File -- Exists: T , Readable: *F*, Dir: T , java.nio.Files -- Exists: T , Readable: *F*, Dir: T --- PATH: /Volumes/USBExtA
*
* --------- Execution Context ----------
* java.version -- 17.0.1
* java.vendor -- Oracle Corporation
* java.vm.version -- 17.0.1+12-LTS-39
* java.vm.vendor -- Oracle Corporation
* java.class.version -- 61.0
* os.name -- Mac OS X
* os.arch -- aarch64
* os.version -- 12.3
*
* java.io.File -- Exists: T , Readable: T , Dir: T , java.nio.Files -- Exists: T , Readable: T , Dir: T --- PATH: /Volumes
* java.io.File -- Exists: T , Readable: *F*, Dir: T , java.nio.Files -- Exists: T , Readable: *F*, Dir: T --- PATH: /Volumes/USBExtA
*/
public class ExtUSBTest {
public static String testPath = "/Volumes/USBExtA/Backups.backupdb/JDCMacBook";
public static void main(String[] args) {
showContext("java.version", "java.vendor", "java.vm.version", "java.vm.vendor", "java.class.version",
"os.name", "os.arch", "os.version");
checkPath(Paths.get(testPath));
}
/** Recursively check all sub-components of the given path - stops if not exists && readable */
public static boolean checkPath(Path path) {
if(path.getParent() == null)
return true;
else if(checkPath(path.getParent()))
return checkThisPath(path);
else
return false;
}
/** Check this particular path to see if exists & readable */
public static boolean checkThisPath(Path path) {
File f = path.toFile();
boolean fExists = f.exists();
boolean fReadable = f.canRead();
boolean fDir = f.isDirectory();
boolean pExists = Files.exists(path);
boolean pReadable = Files.isReadable(path);
boolean pDir = Files.isDirectory(path);
String rslt = String.format("java.io.File -- Exists: %s, Readable: %s, Dir: %s, java.nio.Files -- Exists: %s, Readable: %s, Dir: %s --- PATH: %s",
bstr(fExists), bstr(fReadable), bstr(fDir), bstr(pExists), bstr(pReadable), bstr(pDir), path.toString());
ln(rslt);
return (fExists && fReadable) || (pExists && pReadable);
}
public static void showContext(String ... props) {
ln("--------- Execution Context ----------");
for(int i = 0; i<props.length; i++) showProp(props[i]);
ln("");
}
public static void showProp(String property) {
ln(String.format("%18s -- %s", property, System.getProperty(property)));
}
public static String bstr(boolean b) { return b ? " T " : "*F*";}
public static void ln(String s) { System.out.println(s); }
}
【问题讨论】:
-
可能是您需要授予权限吗?在 System Preferences > Security & Privacy 下有一个 Files and Folders 部分,您可以在其中管理此类权限。
-
@gpunto - 好建议。向 Java 添加了“完全磁盘访问”,但结果没有变化。还在原始文件中添加了一个关键行,即 File.listFiles(..) 返回 NULL 并且 Files.list(path) 在目录不可读时抛出异常。