使用Java IO读取远程共享文件时遭遇FileNotFoundException问题
问题排查:远程共享文件访问失败的原因及修复方案
首先咱们直接说核心问题:你构造的远程共享文件路径完全不符合Windows SMB共享的规范,而且Java的File类本身就不支持直接通过file://格式访问远程SMB共享,这就是抛出FileNotFoundException的根本原因。
你的代码里的两个关键错误
- 路径格式完全错误:你生成的路径是
file:\\10.20.220.187\C:\Users\Administrator\Desktop\KS_testData\test.txt,这种写法是把本地文件路径硬套在IP后面,完全不符合Windows共享的规则。正确的SMB共享路径格式是\\远程IP\共享文件夹名\文件相对路径。比如你要访问目标机器上的C:\Users\Administrator\Desktop\KS_testData\test.txt,首先得把KS_testData这个文件夹设置为共享文件夹(给它起个共享名,比如就叫KS_testData),然后正确的路径应该是\\10.20.220.187\KS_testData\test.txt。 - File类不支持SMB共享访问:Java的
File类只能处理本地文件系统,或者已经映射成本地盘符的网络共享。直接用file://URL初始化File对象,它根本识别不了这是一个远程共享资源。
两种可行的修复方案
方案一:映射网络驱动器(简单快速,适合测试)
先在你的本地机器上,把目标机器的共享文件夹映射成一个本地盘符(比如Z:),步骤大概是:
- 打开资源管理器,右键“此电脑”→“映射网络驱动器”
- 在“文件夹”输入框填
\\10.20.220.187\KS_testData,输入目标机器的账号密码完成映射 - 之后代码就可以像访问本地文件一样读取,修改后的代码如下:
public static void main(String[] args) throws IOException { String fileName = "Z:\\test.txt"; System.out.println(" inputFileName " + fileName); File file = new File(fileName); FileReader inputFileReader = new FileReader(file); BufferedReader inputStream = new BufferedReader(inputFileReader); String inLine = null; while ((inLine = inputStream.readLine()) != null) { System.out.println(inLine); } // 记得关闭流,避免资源泄漏 inputStream.close(); inputFileReader.close(); }
方案二:使用SMBJ库直接访问(推荐,无需手动映射)
如果不想手动映射盘符,可以用专门的SMB客户端库,比如SMBJ(JCIFS的现代替代方案)。
首先引入Maven依赖:
<dependency> <groupId>com.hierynomus</groupId> <artifactId>smbj</artifactId> <version>0.11.6</version> </dependency>
然后修改代码,用SMBJ连接远程共享并读取文件:
import com.hierynomus.msdtyp.AccessMask; import com.hierynomus.msfscc.FileAttributes; import com.hierynomus.mssmb2.SMB2CreateDisposition; import com.hierynomus.mssmb2.SMB2ShareAccess; import com.hierynomus.smbj.SMBClient; import com.hierynomus.smbj.auth.AuthenticationContext; import com.hierynomus.smbj.connection.Connection; import com.hierynomus.smbj.session.Session; import com.hierynomus.smbj.share.DiskShare; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.EnumSet; public class RemoteReadAndWrite { public static void main(String[] args) throws Exception { String ipAddress = "10.20.220.187"; String shareName = "KS_testData"; // 目标机器上设置的共享文件夹名 String fileName = "test.txt"; // 目标机器的账号密码,需拥有该共享的读取权限 String username = "Administrator"; String password = "你的目标机器密码"; SMBClient client = new SMBClient(); try (Connection connection = client.connect(ipAddress)) { AuthenticationContext ac = new AuthenticationContext(username, password.toCharArray(), null); try (Session session = connection.authenticate(ac)) { try (DiskShare share = (DiskShare) session.connectShare(shareName)) { try (BufferedReader reader = new BufferedReader( new InputStreamReader(share.openFile(fileName, EnumSet.of(AccessMask.GENERIC_READ), EnumSet.of(FileAttributes.FILE_ATTRIBUTE_NORMAL), SMB2ShareAccess.ALL, SMB2CreateDisposition.FILE_OPEN, null)))) { String line; while ((line = reader.readLine()) != null) { System.out.println(line); } } } } } } }
额外注意事项
- 确保目标机器的防火墙允许SMB通信(默认端口是445)
- 确保你用来访问的账号拥有该共享文件夹的读取权限
- 如果目标机器是Windows 10/11,可能需要调整SMB协议设置(比如启用SMB 2.0/3.0)
内容的提问来源于stack exchange,提问作者KDS
相关产品推荐
相关产品推荐

