<实战> 用java 代码下载Samba服务器上的文件到本地目录以及上传本地文件到Samba服务器

简介:

引入:

在我们昨天架设好了Samba服务器上并且创建了一个 Samba 账户后,我们就迫不及待的想用JAVA去操作Samba服务器了,我们找到了一个框架叫 jcifs,可以高效的完成我们工作。


实践:

对samba服务器上的操作无外乎2种:一种是从Samba服务器上下载某文件到本地目录,一种是上传本地文件到Samba服务器上指定目录,为此我们写了一个工具类,来完成这两件事情。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package  com.charles.study;
import  java.io.BufferedInputStream;
import  java.io.BufferedOutputStream;
import  java.io.File;
import  java.io.FileInputStream;
import  java.io.FileOutputStream;
import  java.io.IOException;
import  java.io.InputStream;
import  java.io.OutputStream;
import  jcifs.smb.SmbFile;
import  jcifs.smb.SmbFileInputStream;
import  jcifs.smb.SmbFileOutputStream;
/**
  * 这个工具类提供了从Samba服务器上下载文件到本地目录,以及上传本地文件到Samba服务器指定目录的方法
  * @author charles.wang
  *
  */
public  class  SambaFileAccessUtil {
            
     private  SambaFileAccessUtil() {}
            
     /**
      * 从samba服务器上下载指定的文件到本地目录
      * @param remoteFileURL   Samba服务器远程文件的路径
      * @param localDir        本地目录的路径
      */
            
     public  static  void  downloadFileFromSamba(String remoteFileURL, String localDir){
                
         //入参检查
         if  (  (remoteFileURL== null ) || ( "" .equals(remoteFileURL.trim()))){
             System.out.println( "Samba服务器远程文件路径不可以为空" );
             return ;
         }
         //入参检查
         if ( (localDir== null ) || ( "" .equals(localDir.trim()))){
             System.out.println( "本地目录路径不可以为空" );
             return ;
         }
                
         InputStream in =  null ;
         OutputStream out =  null ;
                
         try {
             //创建一个smbFile对象对应远程服务器上的SmbFile
             SmbFile remoteSmbFile =  new  SmbFile(remoteFileURL);
                    
             //获取远程文件的文件名,这个的目的是为了在本地的目录下创建一个同名文件
             String remoteSmbFileName = remoteSmbFile.getName();
                    
             //本地文件由本地目录,路径分隔符,文件名拼接而成
             File localFile =  new  File(localDir+File.separator+remoteSmbFileName);
                    
             //打开文件输入流,指向远程的smb服务器上的文件,特别注意,这里流包装器包装了SmbFileInputStream
             in=  new  BufferedInputStream( new  SmbFileInputStream(remoteSmbFile));
             //打开文件输出流,指向新创建的本地文件,作为最终复制到的目的地
             out =  new  BufferedOutputStream( new  FileOutputStream(localFile));
                    
             //缓冲内存
             byte [] buffer =  new  byte [ 1024 ];
             while  (in.read(buffer) != - 1 ){
                 out.write(buffer);
                 buffer =  new  byte [ 1024 ];
             }     
                    
         } catch  (Exception e){
             e.printStackTrace();
                    
         } finally {
             try   {
                 out.close();
                 in.close();
             catch   (IOException e) {
                 e.printStackTrace();
             }
         }
     }
            
            
     /**
      * 上传本地文件到Samba服务器指定目录
      * @param remoteDirURL  Samba服务器远程目录的路径
      * @param localFilePath 本地文件路径
      */
     public  static  void  uploadFileToSamba(String remoteDirURL,String localFilePath){
                
         //入参检查
         if  (  (remoteDirURL== null ) || ( "" .equals(remoteDirURL.trim()))){
             System.out.println( "Samba服务器远程目录路径不可以为空" );
             return ;
         }
                
         //入参检查
         if ( (localFilePath== null ) || ( "" .equals(localFilePath.trim()))){
             System.out.println( "本地文件路径不可以为空" );
             return ;
         }
                
         InputStream in =  null ;
         OutputStream out =  null ;
                
         try {
             //创建一个本地文件对象
             File localFile =  new  File(localFilePath);
                    
             //获取本地文件的文件名,这个名字用于在远程的Samba服务器上指定目录创建同名文件
             String localFileName = localFile.getName();
                    
             //创建远程服务器上Samba文件对象
             SmbFile remoteSmbFile =  new  SmbFile(remoteDirURL+File.separator+localFileName);
                    
             //打开一个文件输入流执行本地文件,要从它读取内容
             in =  new   BufferedInputStream(  new   FileInputStream(localFile));
                    
             //打开一个远程Samba文件输出流,作为复制到的目的地
             out =  new   BufferedOutputStream(  new   SmbFileOutputStream(remoteSmbFile));
                    
             //缓冲内存
             byte  [] buffer =   new    byte  1024  ];
             while   (in.read(buffer) != -  1  ) {
                 out.write(buffer);
                 buffer =  new  byte 1024  ];
             }
                    
         catch   (Exception e) {
             e.printStackTrace();
                    
         finally   {
             try   {
                 out.close();
                 in.close();
             catch   (IOException e) {
                 e.printStackTrace();
             }
         }
                
     }
}

为了验证我们的正确性,我们写了某测试类。


测试1: 从Samba服务器上下载某文件到本地。

我们先做好准备工作,因为Samba服务器上多半是存图片等资源文件的,所以我们也以图片为例。

我们在Samba服务器的/home/samba/目录下新建一个子目录叫demo1,并且放上去一个图片叫testFile1.jpg,这个文件作为我们要从Samba服务器上下载的目标文件:

111204391.png


然后我们在本地的D:\Framework Study\Samba\DemoTest下创建一个子目录叫demo1,这里作为最终的要下载到本地的目录:

111309374.png


我们运行如下DEMO代码:

1
2
3
4
5
//Demo1: 演示从Samba服务器上下载指定的文件到本地
         System.out.println( "Demo1: Downloading File from Samba Server to Local" );
         String demo1RemoteSambaFileURL=  "smb://samba:samba_password@192.168.71.43/samba/demo1/testFile1.jpg" ;
         String demo1LocalDir =  "D:\\Framework Study\\Samba\\DemoTest\\demo1" ;
         SambaFileAccessUtil.downloadFileFromSamba(demo1RemoteSambaFileURL, demo1LocalDir);


这里注意,我们的Samba服务器上的远程文件URL必须是smb协议开头,因为我们对于samba目录加了访问控制,所以要<username>:<password>@<ip>/<path>的形式,否则,可以吧<username>:<password>去掉。


运行完之后,果然该图片文件被复制到了本地:

111904431.png



测试2:上传本地文件到Samba服务器指定目录

我们同样做好准备工作,我们在本地的D:\Framework Study\Samba\DemoTest下创建一个子目录叫demo2,并且放置一个图片叫testFile2.jpg,这个文件作为要上传到Samba服务器的原始文件:

112125166.png


然后我们在Samba服务器的/home/samba/目录下新建一个子目录叫demo2,这个目录作为我们要上传到的Samba服务器的目录:

112552843.png


我们运行如下的DEMO代码:

1
2
3
4
5
//Demo2: 演示上传文件到Samba服务器指定目录
         System.out.println( "Demo2:Uploading File from Local to Samba Server" );
         String demo2RemoteSambaDirURL= "smb://samba:samba_password@192.168.71.43/samba/demo2" ;
         String demo2LocalFile=  "D:\\Framework Study\\Samba\\DemoTest\\demo2\\testFile2.jpg" ;
         SambaFileAccessUtil.uploadFileToSamba(demo2RemoteSambaDirURL, demo2LocalFile);


运行完之后,果然这个testFile2.jpg被上传到了Samba服务器:

112753600.png



总结:

其实用samba来作为windows和unix类系统之间文件共享的桥梁还是挺方便的,类似unix之间的scp(jsch框架可以完成这件事情) ,其实方法都一样。这里有2个注意点:

(1)在写samba url时候,如果目标目录是一个需要特定账号密码才能访问的,那么这个url pattern为

smb://<samba username>:<samba userpassword>@<samba server ip>/<subpath>,如果某个目录是public的(设了guest ok的),那么url pattern是 smb://<samba server ip>/<subpath>

(2) 这里只提供了上传下载单文件的方法,如果要批上传下载或者操作目录,请递归或者循环调用上面工具类的方法。





本文转自 charles_wang888 51CTO博客,原文链接:http://blog.51cto.com/supercharles888/1344301,如需转载请自行联系原作者
目录
相关文章
|
24天前
|
Java
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
60 9
|
25天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
64 2
|
4天前
|
Java
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
60 34
|
10天前
|
Java 程序员
Java基础却常被忽略:全面讲解this的实战技巧!
小米,29岁程序员,分享Java中`this`关键字的用法。`this`代表当前对象引用,用于区分成员变量与局部变量、构造方法间调用、支持链式调用及作为参数传递。文章还探讨了`this`在静态方法和匿名内部类中的使用误区,并提供了练习题。
15 1
|
21天前
|
安全 Java 开发者
Java 多线程并发控制:深入理解与实战应用
《Java多线程并发控制:深入理解与实战应用》一书详细解析了Java多线程编程的核心概念、并发控制技术及其实战技巧,适合Java开发者深入学习和实践参考。
43 6
|
20天前
|
存储 安全 Java
Java多线程编程中的并发容器:深入解析与实战应用####
在本文中,我们将探讨Java多线程编程中的一个核心话题——并发容器。不同于传统单一线程环境下的数据结构,并发容器专为多线程场景设计,确保数据访问的线程安全性和高效性。我们将从基础概念出发,逐步深入到`java.util.concurrent`包下的核心并发容器实现,如`ConcurrentHashMap`、`CopyOnWriteArrayList`以及`BlockingQueue`等,通过实例代码演示其使用方法,并分析它们背后的设计原理与适用场景。无论你是Java并发编程的初学者还是希望深化理解的开发者,本文都将为你提供有价值的见解与实践指导。 --- ####
|
21天前
|
消息中间件 存储 Java
RocketMQ文件刷盘机制深度解析与Java模拟实现
【11月更文挑战第22天】在现代分布式系统中,消息队列(Message Queue, MQ)作为一种重要的中间件,扮演着连接不同服务、实现异步通信和消息解耦的关键角色。Apache RocketMQ作为一款高性能的分布式消息中间件,广泛应用于实时数据流处理、日志流处理等场景。为了保证消息的可靠性,RocketMQ引入了一种称为“刷盘”的机制,将消息从内存写入到磁盘中,确保消息持久化。本文将从底层原理、业务场景、概念、功能点等方面深入解析RocketMQ的文件刷盘机制,并使用Java模拟实现类似的功能。
38 3
|
24天前
|
Java 测试技术 Maven
Maven clean 提示文件 java.io.IOException
在使用Maven进行项目打包时,遇到了`Failed to delete`错误,尝试手动删除目标文件也失败,提示`java.io.IOException`。经过分析,发现问题是由于`sys-info.log`文件被其他进程占用。解决方法是关闭IDEA和相关Java进程,清理隐藏的Java进程后重新尝试Maven clean操作。最终问题得以解决。总结:遇到此类问题时,可以通过任务管理器清理相关进程或重启电脑来解决。
|
28天前
|
存储 缓存 安全
在 Java 编程中,创建临时文件用于存储临时数据或进行临时操作非常常见
在 Java 编程中,创建临时文件用于存储临时数据或进行临时操作非常常见。本文介绍了使用 `File.createTempFile` 方法和自定义创建临时文件的两种方式,详细探讨了它们的使用场景和注意事项,包括数据缓存、文件上传下载和日志记录等。强调了清理临时文件、确保文件名唯一性和合理设置文件权限的重要性。
50 2
|
17天前
|
存储 人工智能 弹性计算
阿里云弹性计算(ECS)提供强大的AI工作负载平台,支持灵活的资源配置与高性能计算,适用于AI训练与推理
阿里云弹性计算(ECS)提供强大的AI工作负载平台,支持灵活的资源配置与高性能计算,适用于AI训练与推理。通过合理优化资源分配、利用自动伸缩及高效数据管理,ECS能显著提升AI系统的性能与效率,降低运营成本,助力科研与企业用户在AI领域取得突破。
35 6