Java实现:从Windows盘符获取网络驱动器完整路径
解决Java中映射盘符转网络共享路径的问题
原生Windows平台解决方案
网络驱动器映射是Windows独有的特性,原生Java可以通过执行系统命令解析映射关系,替换盘符为完整共享路径:
1. 解析net use输出获取映射表
编写工具类执行net use命令,提取每个盘符对应的网络共享路径:
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.File; import java.util.HashMap; import java.util.Map; public class NetworkDriveUtils { // 获取当前系统的驱动器-共享路径映射 public static Map<String, String> getDriveShareMappings() throws Exception { Map<String, String> driveMap = new HashMap<>(8); Process cmd = Runtime.getRuntime().exec("net use"); try (BufferedReader reader = new BufferedReader(new InputStreamReader(cmd.getInputStream()))) { String line; while ((line = reader.readLine()) != null) { // 匹配包含盘符和UNC路径的行,格式类似 "N: \\shared-drive\docs Microsoft Windows Network" if (line.trim().length() > 0 && line.contains("\\\\")) { String[] segments = line.trim().split("\\s+", 3); if (segments.length >= 2) { driveMap.put(segments[0], segments[1]); } } } } return driveMap; } // 将File对象的盘符路径转换为网络共享路径 public static String toNetworkPath(File file) throws Exception { String absPath = file.getAbsolutePath(); String drive = absPath.substring(0, 2); // 提取盘符如 "N:" Map<String, String> mappings = getDriveShareMappings(); if (mappings.containsKey(drive)) { return mappings.get(drive) + absPath.substring(2); } return absPath; } }
2. 在文件选择逻辑中调用
拿到JFileChooser返回的File对象后,直接调用转换方法:
JFileChooser fileChooser = new JFileChooser(); if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { File selected = fileChooser.getSelectedFile(); String networkPath = NetworkDriveUtils.toNetworkPath(selected); // 这里拿到的就是\\shared-drive\docs\myDir\myFile.dat这类路径 }
注意:不同Windows版本的net use输出格式可能略有差异,需要根据实际环境调整分割或匹配逻辑,且程序需要有执行系统命令的权限。
Java NIO.2 适配方案(Java 7+)
利用NIO.2的文件存储API,遍历系统存储设备识别网络驱动器:
import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.FileSystems; import java.nio.file.FileStore; import java.io.File; public class NioDriveResolver { public static String getNetworkPath(File file) throws Exception { Path path = file.toPath(); Path root = path.getRoot(); if (root == null) return file.getAbsolutePath(); String drive = root.toString().substring(0, 2); for (FileStore store : FileSystems.getDefault().getFileStores()) { // 筛选网络类型的存储设备 if ("Network".equals(store.type())) { String storeName = store.name(); if (storeName.startsWith(drive)) { // 提取共享路径部分 String sharePath = storeName.substring(storeName.indexOf("\\\\")).trim(); return sharePath + path.toString().substring(2); } } } return file.getAbsolutePath(); } }
这个方案无需执行系统命令,但FileStore的名称格式可能因系统而异,需要测试验证。
更可靠的外部库方案(JNA)
如果原生方案适配困难,可以使用JNA直接调用Windows系统APIWNetGetConnection,这是最可靠的方式:
import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.platform.win32.WinDef; import com.sun.jna.platform.win32.WinNT; import java.io.File; public interface MprLibrary extends Library { MprLibrary INSTANCE = Native.load("mpr", MprLibrary.class); // 调用Windows API获取映射驱动器的远程路径 WinNT.DWORD WNetGetConnection(WinDef.LPCSTR localDrive, char[] remotePath, WinDef.DWORD[] bufferLength); } public class JnaDriveResolver { public static String getNetworkPath(File file) throws Exception { String absPath = file.getAbsolutePath(); String drive = absPath.substring(0, 2); char[] remoteBuffer = new char[256]; WinDef.DWORD[] bufferLen = new WinDef.DWORD[]{new WinDef.DWORD(remoteBuffer.length)}; WinNT.DWORD result = MprLibrary.INSTANCE.WNetGetConnection(drive, remoteBuffer, bufferLen); if (result.intValue() == 0) { String sharePath = new String(remoteBuffer).trim(); return sharePath + absPath.substring(2); } return absPath; } }
JNA可以从源码构建,也可以通过Maven/Gradle引入依赖,这个方案直接和系统交互,比命令解析更稳定。
内容的提问来源于stack exchange,提问作者carrj-nm
相关产品推荐
相关产品推荐

