java samba 客户端

117 篇文章 0 订阅

最近需用使用java访问linux下的共享目录,实现文件下载和上传, 由于linux共享文件主要采用两种方式,samba和NFS,samba是基于Microsoft的smb/cifs协议, NFS网络文件系统(Network File System)则是另一种协议. 对这两种方式的配置和实现代码如下:(配置在Ubuntu下完成) 

    一,samba 

       (1)配置: 

             a ) 建立共享目录: mkdir /home/pirate/smbshare,  chmod 777 smbshare 

             b) 安装samba, sudo apt-get install samba,  sudo apt-get install smbfs 

             c) 修改samba配置文件, sudo gedit /etc/samba/smb.conf, 在文件最后添加如下行: 


               [smbshare]  #-----共享名字, 客户端访问时需使用这个名字 
               path = /home/pirate/smbshare  
               available = yes 
               browsealbe = yes 
               public = yes 
               writable = yes 

     d)  创建共享用户: sudo useradd aaa 

      f)  重启samba, sudo /etc/init.d/samba restart 

(2)  java访问

   

    访问Samba共享依赖于一个第三方包:jcifs-1.3.15.jar, 下载地址http://jcifs.samba.org/

Java代码   收藏代码
  1. public void downloadViaShare(final String ip,final String user,final String password,final String <span style="color: #000000;">dir</span>)  
  2.     {  
  3.         logger.debug("Share(SMB) download!");  
  4.           
  5.         String newDir = dir;          
  6.         String url = "";    
  7.         SmbFile [] fileList = null;  
  8.         FileOutputStream fos = null;  
  9.         SmbFileInputStream smbIs = null;  
  10.         byte [] buffer = new byte[8192];  
  11.         int readBytes = 0;  
  12.         int totalBytes = 0;  
  13.               
  14.         if (!dir.endsWith("/"))  //directory must end with "/"        
  15.                                 newDir = dir+"/";    
  16.         url = "smb://"+user+":"+password+"@"+ip+"/"+newDir;  
  17.           
  18.         long startTime = System.currentTimeMillis();  
  19.         try {  
  20.             SmbFile shareDir = new SmbFile(url);  
  21.             if(shareDir.isDirectory())  
  22.             {  
  23.                 fileList = shareDir.listFiles();    
  24.                 for(int i=0;i<fileList.length;i++)    
  25.                 {  
  26.                     if(fileList[i].isFile())  
  27.                     {  
  28.                         smbIs = new SmbFileInputStream((SmbFile)fileList[i]);  
  29.                         fos = new FileOutputStream(new File(tempDir+File.separator+fileList[i].getName()));  
  30.                         while((readBytes = smbIs.read(buffer)) > 0 )  
  31.                         {  
  32.                             fos.write(buffer,0,readBytes);  
  33.                             totalBytes += readBytes;  
  34.                         }  
  35.                         smbIs.close();  
  36.                         fos.close();  
  37.                         logger.debug(fileList[i].getName() + " is downloaded!");  
  38.                         try  
  39.                         {  
  40.                             fileList[i].delete();    
  41.                         }catch(SmbAuthException smbae )  
  42.                         {  
  43.                             logger.debug(fileList[i].getName()+" can not be deleted!");  
  44.                         }  
  45.                     }  
  46.                 }  
  47.                 long endTime = System.currentTimeMillis();  
  48.                 long timeTaken = endTime-startTime;  
  49.                 logger.debug(totalBytes +"bytes downloaded in " + timeTaken/1000 + " seconds at "+ (( totalBytes / 1000 ) / Math.max( 1, ( timeTaken / 1000 ))) + "Kb/sec");  
  50.             }  
  51.         }catch(MalformedURLException urle)  
  52.         {  
  53.             logger.debug("Incorrect URL format!");  
  54.         }catch (SmbException smbe) {  
  55.             smbe.printStackTrace();  
  56.             logger.debug(this.getClass().getName()+"||"+smbe.getMessage());  
  57.         }catch(IOException ioe)  
  58.         {  
  59.             ioe.printStackTrace();  
  60.             logger.debug(this.getClass().getName()+"||"+ioe.getMessage());  
  61.         }finally  
  62.         {  
  63.             try  
  64.             {  
  65.                 smbIs.close();  
  66.                 fos.close();  
  67.             }catch(Exception smbe)  
  68.             {  
  69.                 logger.debug(this.getClass().getName()+"||"+smbe.getMessage());  
  70.             }  
  71.         }  
  72.           
  73.     }  

 

二,NFS

      (1) 配置

          a) 安装NFS, sudo apt-get install nfs-kernel-server

          b) 建立共享目录: mkdir /home/pirate/nfsshare

          c) 编辑配置:  sudo gedit /etc/exports ,在最后添加如下行:

                 /home/pirate/nfsshare  *(rw,sync,no_all_squash),含义为:

                 共享目录 允许访问的网络段(读写权限,数据发送方式,客户端权限)

 其它Ubuntu nfs常用的参数有:
ro 只读访问
rw 读写访问sync 所有数据在请求时写入共享
async nfs在写入数据前可以响应请求
secure nfs通过1024以下的安全TCP/IP端口发送
insecure nfs通过1024以上的端口发送
wdelay 如果多个用户要写入nfs目录,则归组写入(默认)
no_wdelay 如果多个用户要写入nfs目录,则立即写入,当使用async时,无需此设置。
hide 在nfs共享目录中不共享其子目录
no_hide 共享nfs目录的子目录
subtree_check 如果共享/usr/bin之类的子目录时,强制nfs检查父目录的权限(默认)
no_subtree_check 和上面相对,不检查父目录权限
all_squash 共享文件的UID和GID映射匿名用户anonymous,适合公用目录。
no_all_squash 保留共享文件的UID和GID(默认)
root_squash root用户的所有请求映射成如anonymous用户一样的权限(默认)
no_root_squas root用户具有根目录的完全管理访问权限
anonuid=xxx 指定nfs服务器/etc/passwd文件中匿名用户的UID
anongid=xxx 指定nfs服务器/etc/passwd文件中匿名用户的GID

d)  重启 NFS: sudo service portmap restart , sudo service nfs-kernel-server restart

e)  测试: showmount -e,查看是否有该目录的共享

(2)  代码

话说这段代码虽然很简单,却费了我不少力气。JDK本身是没有访问NFS的功能,只能用第三方包了,google后发觉用java访问NFS的应用很少,竟然没找到可用的示例,远不如samba那么多,而且只有sun的webnfs可用来访问NFS,在http://yanfs.dev.java.net  上只有一个一个的散装源码, 打包后的jar都没地方下,连API文档都没有. 愁煞我也. 找来找去,根据sun的在线文档摸索出了点头绪.

 

 

Java代码   收藏代码
  1. public void downloadViaNFS(final String ip,final String user,final String password,final String dir)  
  2.     {  
  3.         logger.debug("NFS download begin!");  
  4.         try {      
  5.               
  6.             String url = "nfs://"+ip+"/"+dir;               
  7.                     XFile xf = new XFile(url);  
  8.             if (xf.exists())  
  9.             {  
  10.                 logger.debug("URL is OK!");  
  11.             }else  
  12.             {  
  13.                 logger.debug("URL is bad!");  
  14.                 return;  
  15.             }  
  16.                           
  17.             XFileExtensionAccessor nfsx = (XFileExtensionAccessor)xf.getExtensionAccessor();  
  18.             if(!nfsx.loginPCNFSD(ip, user, password))  
  19.             {  
  20.                 logger.debug("login failed!");return;  
  21.             }  
  22.               
  23.             String [] fileList = xf.list();  
  24.             XFile temp = null;  
  25.             long startTime = System.currentTimeMillis();  
  26.             int filesz = 0;  
  27.             for(String file:fileList)  
  28.             {  
  29.                 temp = new XFile(url+"/"+file);  
  30.                 XFileInputStream  in  = new XFileInputStream(temp)  ;  
  31.                 XFileOutputStream out = new XFileOutputStream(tempDir+File.separator+file);  
  32.   
  33.                 int c;          
  34.                 byte[] buf = new byte[8196];             
  35.                   
  36.                           
  37.   
  38.                 while ((c = in.read(buf)) > 0) {                  
  39.                      filesz += c;                  
  40.                      out.write(buf, 0, c);                       
  41.                 }              
  42.   
  43.                 logger.debug(file +" is downloaded!");         
  44.                 in.close();              
  45.                 out.close();          
  46.                 if (temp.canWrite())  
  47.                 {  
  48.                     temp.delete();  
  49.                     logger.debug(file + " is deleted!");  
  50.                 }else  
  51.                 {  
  52.                     logger.debug(file + " can not be delted!");  
  53.                 }  
  54.             }  
  55.                 long endTime = System.currentTimeMillis();  
  56.                 long timeDiff = endTime - startTime;  
  57.                 int rate = (int) ((filesz /1000) / (timeDiff / 1000.0));  
  58.                 logger.debug(filesz + " bytes copied @ " + rate + "Kb/sec");  
  59.              
  60.             }catch (IOException e) {          
  61.                 logger.debug(e);          
  62.             }  
  63.           
  64.     } 
  • 首先在Linux上创建一个共享文件夹

mkdir /home/user/share

  • 用root用户启动samba服务

service smb start

  • 修改smb.conf文件

sudo gedit /etc/samba/smb.conf 或者 vi /etc/samba/smb.conf

[share]

path = /home/user/share

...

writable = yes

  • 创建共享用户并设置密码

sudo useradd smbusr

sudo smbpasswd -a smbusr

使用命令 sudo smbpasswd -x 删除用户

  • 重启samba服务

service smb restart

  • 测试

在windows中输入//192.168.0.94,并输入用户名密码smbusr/***,看能不能访问到共享文件夹。如果可以的话拷贝一份本地txt文件到此目录,并在linux中查看此文件是否存在,如果用vi能够打开文件文件并正常查看其内容,congruatulations!

  • 用jcifs测试文件操作

去下 载适当版本的jcifs,将jcifs-1.3.14.jar加入到项目工程中。写个测试类共享文件操作:

[java]  view plain copy
  1. public static void main(String[] args) {  
  2.           
  3.         FileInputStream fis = null;  
  4.         SmbFileOutputStream sfos = null;  
  5.         try {  
  6.             fis = new FileInputStream(new File("c:/source.txt"));  
  7.             sfos = new SmbFileOutputStream(new SmbFile("smb://smbusr:smbusr@192.168.1.94/smbusr/dest.txt"));  
  8.               
  9.             byte [] buffer = new byte[1024];  
  10.             int c = 0;  
  11.             while ((c = fis.read(buffer)) != -1) {  
  12.                 sfos.write(buffer);  
  13.             }  
  14.         } catch (SmbException e) {  
  15.             e.printStackTrace();  
  16.         } catch (MalformedURLException e) {  
  17.             e.printStackTrace();  
  18.         } catch (UnknownHostException e) {  
  19.             e.printStackTrace();  
  20.         } catch (IOException e) {  
  21.             e.printStackTrace();  
  22.         }  
  23.           
  24.         finally {  
  25.             try {  
  26.                 fis.close();  
  27.                 sfos.close();  
  28.                   
  29.             } catch (IOException e) {  
  30.                 e.printStackTrace();  
  31.             }  
  32.         }  
  33.     }  

SAMBA的JAVA客户端JCIFS 

首页 
http://jcifs.samba.org/ 

下载文件 
jcifs-1.2.25b.zip 

下载的版本很新啊。能从MAVEN上搞到的版本如下pom.xml 
<dependency> 
<groupId>org.samba.jcifs</groupId> 
<artifactId>jcifs</artifactId> 
<version>1.2.15</version> 
</dependency> 

提供调用的static 工具类SambaUtil.java: 
package com.sillycat.api.commons.utils; 

import java.net.MalformedURLException; 

import jcifs.smb.SmbException; 
import jcifs.smb.SmbFile; 
import jcifs.smb.SmbFileInputStream; 
import jcifs.smb.SmbFileOutputStream; 

public class SambaUtil { 

public static void delete(String filepath, String username, String pwd) 
    { 
   SmbFile f = null; 
   try { 
    f = new SmbFile("smb://" + username + ":" + pwd + "@" 
      + filepath); 
    try { 
     if (f.exists()) { 
      f.delete(); 
     } 
    } catch (SmbException e) { 
     e.printStackTrace(); 
    } 
   } catch (MalformedURLException e) { 
    e.printStackTrace(); 
   } 
  


public static boolean exists(String filepath, String username, String pwd) 
    throws Exception { 
   SmbFile file = new SmbFile("smb://" + username + ":" + pwd + "@" 
     + filepath); 
   try { 
    return file.exists(); 
   } catch (Exception e) { 
    e.printStackTrace(); 
    return false; 
   } 


public static boolean filerename(String filepath, String newFilename, 
    String username, String pwd) { 
   try { 
    SmbFile f = new SmbFile("smb://" + username + ":" + pwd + "@" 
      + filepath); 
    if (f.isFile()) { 
     String str = filepath.substring(0, filepath.lastIndexOf("/")); 
     str = "smb://" + username + ":" + pwd + "@" + str + "/" 
       + newFilename; 
     f.renameTo(new SmbFile(str)); 
    } else if (f.isDirectory()) { 
     String str = filepath.substring(0, filepath.length() - 1); 
     str = filepath.substring(0, str.lastIndexOf("/")); 
     str = "smb://" + username + ":" + pwd + "@" + str + "/" 
       + newFilename; 
     f.renameTo(new SmbFile(str)); 
    } 
    return true; 
   } catch (Exception e) { 
    e.printStackTrace(); 
    return false; 
   } 


public static void mkdir(String dir, String username, String pwd) { 
   try { 
    SmbFile f = new SmbFile("smb://" + username + ":" + pwd + "@" + dir); 
    if (!f.exists()) { 
     f.mkdir(); 
    } 
   } catch (Exception e) { 
    e.printStackTrace(); 
   } 


public static void mkfile(String filepath, String username, String pwd) { 
   try { 
    SmbFile f = new SmbFile("smb://" + username + ":" + pwd + "@" 
      + filepath); 
    if (!f.exists()) { 
     f.createNewFile(); 
    } 
   } catch (Exception e) { 
    e.printStackTrace(); 
   } 


public static void mkfile(String filepath, String username, String pwd, 
    String content) { 
   try { 
    SmbFile f = new SmbFile("smb://" + username + ":" + pwd + "@" 
      + filepath); 
    if (!f.exists()) 
     f.createNewFile(); 
    writefile(filepath, content, username, pwd); 
   } catch (Exception e) { 
    e.printStackTrace(); 
   } 


public static String readfile(String filepath, String username, String pwd) { 
   StringBuffer sb = new StringBuffer(""); 
   try { 
    SmbFile f = new SmbFile("smb://" + username + ":" + pwd + "@" 
      + filepath); 
    if (f.exists() && f.isFile()) { 
     int length = f.getContentLength();// 得到文件的大小 
     byte buffer[] = new byte[length]; 

     SmbFileInputStream in = new SmbFileInputStream(f); 
     while ((in.read(buffer)) != -1) { 
      sb.append(new String(buffer)); 
     } 
     in.close(); 
    } 
   } catch (Exception e) { 
    e.printStackTrace(); 
   } 
   return sb.toString(); 


public static boolean isdir(String filepath, String username, String pwd) 
    throws Exception { 
   String dir = "smb://" + username + ":" + pwd + "@" + filepath; 
   SmbFile f = new SmbFile(dir); 
   return f.isDirectory(); 


public static void writefile(String filepath, String content, 
    String username, String pwd) { 
   try { 
    SmbFile to = new SmbFile("smb://" + username + ":" + pwd + "@" 
      + filepath); 
    SmbFileOutputStream out = new SmbFileOutputStream(to); 
    out.write(content.getBytes()); 
    out.close(); 
   } catch (Exception e) { 
    e.printStackTrace(); 
   } 





测试类SambaUtilTest.java: 
package com.sillycat.api.commons.utils; 

import junit.framework.TestCase; 

public class SambaUtilTest extends TestCase { 

protected void setUp() throws Exception { 
   super.setUp(); 


protected void tearDown() throws Exception { 
   super.tearDown(); 


public void testDummy() { 
   assertTrue(true); 


public void testCreateDir() { 
   String dir = "www.sillycat.com/share/test1"; 
   SambaUtil.mkdir(dir, "guest", "guest"); 
   SambaUtil.mkfile(dir + "/test2.txt", "guest", "guest", "<html></html>中文hello world!"); 
   String tmp = SambaUtil.readfile(dir + "/test2.txt", "guest", "guest"); 
   System.out.println(tmp); 
   SambaUtil.delete(dir + "/test2.txt", "guest", "guest"); 




报错: 
jcifs.smb.SmbException: The network name cannot be found. 

原来是我的filepath写错了,写成www.sillycat.com/test1 
改成www.sillycat.com/share/test1就OK了 

报错: 
jcifs.smb.SmbException: The process cannot access the file because it is being used by another process. 

原来是方法里面的 
SmbFileInputStream in = new SmbFileInputStream(f); 
SmbFileOutputStream out = new SmbFileOutputStream(to); 
这个in 和 out 都要注意 close,我有一个忘记close了。。。汗 


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值