业务需求,需要读取局域网内的任意PC上的文件,用java
去实现,查阅资料,结合window
的文件共享功能和SmbFile
类的支持可以实现这个功能。
SMB
一种客户机/服务器、请求/响应协议。通过SMB
协议,客户端应用程序可以在各种网络环境下读、写服务器上的文件,以及对服务器程序提出服务请求。此外通过SMB
协议,应用程序可以访问远程服务器端的文件、以及打印机、邮件槽(mailslot
)、命名管道(named pipe
)等资源。
jcifs的开发方法类似java的文件操作功能,它的资源url定位:
smb://{user}:{password}@{host}/{path},
smb为协议名,user和password分别为共享文件机子的登陆名和密码,@后面是要访问的资源的主机名或IP地址。最后是资源的共享文件夹名称和共享资源名。
例如smb://administrator:122122@192.168.0.22/test/response.txt。
在JAVA程序中,使用如下方式获得一个远程共享文件(设置共享文件的权限——读取、修改、完全控制)的句柄:SmbFile file = newSmbFile("smb://guest:1234@192.168.3.56/share/a.txt");
这里的句柄不仅限于远程的共享文件,还可能是共享文件夹。
isFile()方法和isDirectory()用来判断这个句柄对应的资源的真实属性。如果是共享文件夹,通过调用它的list()方法将获得其中资源的列表。
List方法支持过滤器机制,有两种过滤器可供使用,一种是SmbFileFilter,另一种是SmbFilenameFilter
,这两个在jcifs中作为接口出现,你可以根据自己的需要派生出个性化的过滤器,实现接口中的accept方法,以满足不同业务的需求。
SmbFileInputStream 是smb 文件的输入流,它的功能是以流的方式打开一个SmbFile:SmbFileInputStream
in = new SmbFileInputStream(file);SmbFileInputStream提供read方法,你可以从这个流中读出远程文件全部的内容。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
开启共享
首先在服务机上新建好要共享的文件夹,具体方法可以参考上一节的总结:
添加依赖
有了可以共享的文件夹后,我们就可以在项目中去使用它了,如果你的项目是使用的Maven来构建的,那么很简单,在你项目的
pom.xml
文件夹中添加如下的依赖就可以引用所有的SmbFile
类的jar
包了。
<dependency>
<groupId>jcifs</groupId>
<artifactId>jcifs</artifactId>
<version>1.3.17</version>
</dependency>
- 1
- 2
- 3
- 4
- 5
文件读写
这一部分主要总结平常对文件的一些操作,例如读取,复制,写入,删除等操作。
读取文件
//主要利用类 SmbFile 去实现读取共享文件夹 shareFile 下的所有文件(文件夹)的名称
String URL="smb://192.168.0.100/shareFile/";
// String URL="smb://xxx:xxx@192.168.0.100/shareFile/";
SmbFile smbfile=new SmbFile(URL);
try {
if(!smbfile.exists()){
System.out.println("no such folder");
}
else{
SmbFile[] files = smbfile.listFiles();
for (SmbFile f : files) {
System.out.println(f.getName());
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
上传文件
//从本地读取文件上传到服务主机中
String url_local="c://text.txt";
String URL_remote="smb://192.168.0.100/shareFile/uploadFile.txt";
File localfile=new File(url);
InputStream ins = new FileInputStream(localfile);
SmbFile smbfile=new SmbFile(URL_remote);
if(smbfile.exists()){
System.out.println("file is exists");
}else{
smbFile.connect();
OutputStream outs = new SmbFileOutputStream(smbfile);
byte[] buffer = new byte[4096];
int len = 0; //读取长度
while ((len = ins.read(buffer, 0, buffer.length)) != -1) {
outs.write(buffer, 0, len);
}
outs.flush(); //刷新缓冲的输出流
System.out.println("写入成功");
}
//注意SmbFile本来就不稳定,一定要注意把所有的流关闭啊。try-catch挺烦的,用IDE自己生成吧!
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
删除文件
String url = "smb://192.168.1.116/ShareFile/test.txt";
SmbFile file=new SmbFile(url);
if(file.exists()){
file.delete();
System.out.println("delete the file");
}
//自己捕获异常,补上try-catch 即可
- 1
- 2
- 3
- 4
- 5
- 6
- 7
总结
在使用的
SmbFile
来创建文件和文件夹的时候,发现他不能支持像File
类一样的直接构造文件夹和文件的构造函数,File(String parent,String fileName)
,但是SmbFile
会将文件名组装到文件夹中生成文件夹,没办法,只能先生成parent folder
然后去创建文件。