Java 11下NIO操作Windows网络路径时方法匹配失败求助
问题
使用Java 11.0.11(Amazon Corretto版本),代码运行在身份治理系统的BeanShell文件中。尝试用java.nio方法操作Windows网络路径:能通过Path.of、Paths.get等方法创建sun.nio.fs.WindowsPath对象,但调用Files.exists()、Files.createDirectory()等java.nio方法时,均报错提示找不到支持sun.nio.fs.WindowsPath参数的对应方法。使用java.io方法可正常运行,但因需支持符号链接及更好的错误处理,希望解决NIO的问题。请问是否有现成的Windows网络文件夹管理包?若无法解决,计划用PowerShell脚本实现,但不想放弃已完成的Java逻辑。
附代码
import lava.lang.*; import java.nio.*; import java.io.*; String Folder = "//idg-bridge/C$/TEMP/HomeDriveTest/testusername"; Path fnew = Path.of(Folder,new String[0]); if(!Files.exists(fnew, LinkOption.NOFOLLOW_LINKS)) { Files.createDirectory(fnew); }
报错信息
调用Files.exists(fnew, LinkOption.NOFOLLOW_LINKS)时:
Error in method invocation: Static method exists( sun.nio.fs.WindowsPath, java.nio.file.LinkOption ) not found in class'java.nio.file.Files'
改用java.io的(new File("//idg-bridge/C$/TEMP/HomeDriveTest/testusername")).exists()通过检查后,在Files.createDirectory(fnew)处报错:
Error in method invocation: Static method createDirectory( sun.nio.fs.WindowsPath ) not found in class'java.nio.file.Files'
解决方案
1. 修复BeanShell的类型匹配问题
BeanShell对Java泛型和类型继承的处理存在局限性,无法识别WindowsPath是java.nio.file.Path的实现类,进而找不到对应重载方法。解决核心是显式声明变量类型为java.nio.file.Path,同时补充完整的包导入:
import lava.lang.*; import java.nio.file.*; // 导入完整的nio.file包,而非仅java.nio.* import java.io.*; String Folder = "//idg-bridge/C$/TEMP/HomeDriveTest/testusername"; // 显式声明类型为java.nio.file.Path,避免动态类型推断问题 java.nio.file.Path fnew = Path.of(Folder); if (!Files.exists(fnew, LinkOption.NOFOLLOW_LINKS)) { Files.createDirectory(fnew); }
2. 无需额外第三方包
Java NIO本身已支持Windows网络路径(SMB共享),只要解决BeanShell的类型识别问题即可,不需要额外的Windows网络文件夹管理包。
3. 备用方案:Java调用PowerShell保留原有逻辑
如果BeanShell的类型问题无法解决,可保留现有Java逻辑,通过ProcessBuilder调用PowerShell完成操作:
import java.io.*; String Folder = "\\\\idg-bridge\\C$\\TEMP\\HomeDriveTest\\testusername"; // 构建PowerShell命令,实现目录检查与创建 String[] cmd = { "powershell.exe", "-Command", "if(!(Test-Path -Path '" + Folder + "' -PathType Directory -Resolve)) { New-Item -Path '" + Folder + "' -ItemType Directory }" }; ProcessBuilder pb = new ProcessBuilder(cmd); pb.redirectErrorStream(true); Process process = pb.start(); // 读取输出用于调试(可选) BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } process.waitFor();
内容的提问来源于stack exchange,提问作者Chris

