Java实现跨Windows PC文件复制:未映射驱动器认证失败求助
这个问题我太熟悉了——你遇到的本质问题是:当你直接访问远程Windows共享的UNC路径(比如\\remote-host\shared-dir)时,Java的File类和Apache Commons IO的FileUtils不会自动帮你传递身份凭据;而映射驱动器的时候你已经提前输入过用户名密码,系统缓存了这些凭据,所以程序能正常运行;但没映射驱动器或者没登录过远程PC时,系统没有可用的凭据,就会抛出你看到的错误:
java.io.IOException: The user name or password is incorrect
at java.io.WinNTFileSystem.canonicalize0(Native Method)
at java.io.Win32FileSystem.canonicalize(Win32FileSystem.java:414)
at java.io.File.getCanonicalPath(File.java:618)
at org.apache.commons.io.FileUtils.copyFile(FileUtils.java:...
下面给你两种实用的解决方案:
方案1:提前通过Windows命令行建立网络连接(简单快速)
在你的Java程序执行文件复制操作前,先通过net use命令建立带身份验证的网络连接,让系统缓存凭据:
net use \\remote-pc\shared-folder /user:REMOTE-PC\username your-password
执行完这个命令后,再运行你的Java程序,FileUtils.copyFile就能正常访问远程路径了。如果不需要长期保持连接,复制完成后可以用下面的命令断开:
net use \\remote-pc\shared-folder /delete
你可以在Java代码里通过Runtime.getRuntime().exec()来执行这些命令,记得处理命令的输出和错误流,避免程序阻塞。
方案2:在Java代码中集成身份验证(更优雅的程序级解决方案)
如果你不想依赖外部命令,可以用JNA(Java Native Access)调用Windows的WNetAddConnection2 API,直接在代码里传递凭据建立连接。
步骤1:引入JNA依赖
如果用Maven,在pom.xml里添加:
<dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> <version>5.13.0</version> </dependency> <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna-platform</artifactId> <version>5.13.0</version> </dependency>
步骤2:编写连接和复制的代码
import com.sun.jna.platform.win32.WinNetWk; import com.sun.jna.platform.win32.W32Errors; import org.apache.commons.io.FileUtils; import java.io.File; import java.io.IOException; public class RemoteFileCopier { public static void main(String[] args) { String remotePath = "\\\\remote-pc\\shared-folder\\target-file.txt"; String localPath = "C:\\local\\source-file.txt"; String remoteUser = "REMOTE-PC\\username"; String remotePassword = "your-password"; // 建立远程连接 WinNetWk.NETRESOURCE resource = new WinNetWk.NETRESOURCE(); resource.lpRemoteName = remotePath.substring(0, remotePath.lastIndexOf("\\")); // 只取共享目录路径 resource.dwType = WinNetWk.RESOURCETYPE_DISK; int result = WinNetWk.INSTANCE.WNetAddConnection2(resource, remotePassword, remoteUser, 0); if (result != W32Errors.NO_ERROR) { System.err.println("Failed to establish remote connection: error code " + result); return; } try { // 执行文件复制 FileUtils.copyFile(new File(localPath), new File(remotePath)); System.out.println("File copied successfully!"); } catch (IOException e) { e.printStackTrace(); } finally { // 断开连接 WinNetWk.INSTANCE.WNetCancelConnection2(resource.lpRemoteName, WinNetWk.CONNECT_UPDATE_PROFILE, false); } } }
注意事项
- 确保远程Windows PC的共享文件夹已经开启,并且你使用的用户有读写权限
- 如果远程PC不在同一个域,用户名要写成
远程PC名称\用户名的格式 - 处理
WNetAddConnection2返回的错误码,比如错误码1219表示已经存在相同的连接,这时候可以跳过建立连接直接复制
内容的提问来源于stack exchange,提问作者learner

