注:java 访问NFS 目录 不好搞,
转换了一下思路,既然一直无法成功访问NFS服务。就直接索性操作本地挂载点。针对本地挂载的路径进行文件的读写操作。这样就达到了操作NFS共享目录的效果。
最近需用使用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访问
Java代码
public void downloadViaShare(final String ip,final String user,final String password,final String dir)
{
logger.debug("Share(SMB) download!");
String newDir = dir;
String url = "";
SmbFile [] fileList = null;
FileOutputStream fos = null;
SmbFileInputStream smbIs = null;
byte [] buffer = new byte[8192];
int readBytes = 0;
int totalBytes = 0;
if (!dir.endsWith("/")) //directory must end with "/"
newDir = dir+"/";
url = "smb://"+user+":"+password+"@"+ip+"/"+newDir;
long startTime = System.currentTimeMillis();
try {
SmbFile shareDir = new SmbFile(url);
if(shareDir.isDirectory())
{
fileList = shareDir.listFiles();
for(int i=0;i { if(fileList[i].isFile()) { smbIs = new SmbFileInputStream((SmbFile)fileList[i]); fos = new FileOutputStream(new File(tempDir+File.separator+fileList[i].getName())); while((readBytes = smbIs.read(buffer)) > 0 ) { fos.write(buffer,0,readBytes); totalBytes += readBytes; } smbIs.close(); fos.close(); logger.debug(fileList[i].getName() + " is downloaded!"); try { fileList[i].delete(); }catch(SmbAuthException smbae ) { logger.debug(fileList[i].getName()+" can not be deleted!"); } } } long endTime = System.currentTimeMillis(); long timeTaken = endTime-startTime; logger.debug(totalBytes +"bytes downloaded in " + timeTaken/1000 + " seconds at "+ (( totalBytes / 1000 ) / Math.max( 1, ( timeTaken / 1000 ))) + "Kb/sec"); } }catch(MalformedURLException urle) { logger.debug("Incorrect URL format!"); }catch (SmbException smbe) { smbe.printStackTrace(); logger.debug(this.getClass().getName()+"||"+smbe.getMessage()); }catch(IOException ioe) { ioe.printStackTrace(); logger.debug(this.getClass().getName()+"||"+ioe.getMessage()); }finally { try { smbIs.close(); fos.close(); }catch(Exception smbe) { logger.debug(this.getClass().getName()+"||"+smbe.getMessage()); } } } 二,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代码 public void downloadViaNFS(final String ip,final String user,final String password,final String dir) { logger.debug("NFS download begin!"); try { String url = "nfs://"+ip+"/"+dir; XFile xf = new XFile(url); if (xf.exists()) { logger.debug("URL is OK!"); }else { logger.debug("URL is bad!"); return; } XFileExtensionAccessor nfsx = (XFileExtensionAccessor)xf.getExtensionAccessor(); if(!nfsx.loginPCNFSD(ip, user, password)) { logger.debug("login failed!");return; } String [] fileList = xf.list(); XFile temp = null; long startTime = System.currentTimeMillis(); int filesz = 0; for(String file:fileList) { temp = new XFile(url+"/"+file); XFileInputStream in = new XFileInputStream(temp) ; XFileOutputStream out = new XFileOutputStream(tempDir+File.separator+file); int c; byte[] buf = new byte[8196]; while ((c = in.read(buf)) > 0) { filesz += c; out.write(buf, 0, c); } logger.debug(file +" is downloaded!"); in.close(); out.close(); if (temp.canWrite()) { temp.delete(); logger.debug(file + " is deleted!"); }else { logger.debug(file + " can not be delted!"); } } long endTime = System.currentTimeMillis(); long timeDiff = endTime - startTime; int rate = (int) ((filesz /1000) / (timeDiff / 1000.0)); logger.debug(filesz + " bytes copied @ " + rate + "Kb/sec"); }catch (IOException e) { logger.debug(e); } } 二,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代码 public void downloadViaNFS(final String ip,final String user,final String password,final String dir) { logger.debug("NFS download begin!"); try { String url = "nfs://"+ip+"/"+dir; XFile xf = new XFile(url); if (xf.exists()) { logger.debug("URL is OK!"); }else { logger.debug("URL is bad!"); return; } XFileExtensionAccessor nfsx = (XFileExtensionAccessor)xf.getExtensionAccessor(); if(!nfsx.loginPCNFSD(ip, user, password)) { logger.debug("login failed!");return; } String [] fileList = xf.list(); XFile temp = null; long startTime = System.currentTimeMillis(); int filesz = 0; for(String file:fileList) { temp = new XFile(url+"/"+file); XFileInputStream in = new XFileInputStream(temp) ; XFileOutputStream out = new XFileOutputStream(tempDir+File.separator+file); int c; byte[] buf = new byte[8196]; while ((c = in.read(buf)) > 0) { filesz += c; out.write(buf, 0, c); } logger.debug(file +" is downloaded!"); in.close(); out.close(); if (temp.canWrite()) { temp.delete(); logger.debug(file + " is deleted!"); }else { logger.debug(file + " can not be delted!"); } } long endTime = System.currentTimeMillis(); long timeDiff = endTime - startTime; int rate = (int) ((filesz /1000) / (timeDiff / 1000.0)); logger.debug(filesz + " bytes copied @ " + rate + "Kb/sec"); }catch (IOException e) { logger.debug(e); } }