linux共享文件samba安装与java读取外部文件夹方法

时间:2023-08-13 12:57:08

测试环境RedHat 6.4

一.安装

samba组件安装:

(1)首先用“rpm –qa |grep samba”命令检验系统samba服务是否安装。

#rpm –qa |grep samba

samba-common-3.6.9-151.el6.x86_64.rpm

samba-winbind-3.6.9-151.el6.x86_64.rpm

samba-winbind-clients-3.6.9-151.el6.x86_64.rpm

samba-3.6.9-151.el6.x86_64.rpm

(2)如果没有显示samba(版本)信息,则说明没有安装,利用“RedHat Linux安装光盘”里自带的RPM包进行安装(也可自己在网上下载相关的版本包进行安装)。(可以通过压缩工具打开RedHat的镜像iso文件,在rpm包目录下可以找到相关samba的包)

rpm -ivh samba-common-3.6.9-151.el6.x86_64.rpm -f --nodeps

rpm -ivh samba-winbind-3.6.9-151.el6.x86_64.rpm -f --nodeps

rpm -ivh samba-winbind-clients-3.6.9-151.el6.x86_64.rpm -f --nodeps

rpm -ivh samba-3.6.9-151.el6.x86_64.rpm -f –nodeps

rpm -ivh samba4-libs-4.0.0-55.el6.rc4.x86_64.rpm –f –nodeps

rpm -ivh samba-client-3.6.9-151.el6.x86_64.rpm –f -nodeps

卸载命令:# rpm -e [包名]

或者强制卸载: # rpm -e --nodeps [包名]

二.Samba的smb.conf文件配置

cd /etc/samba

mv smb.conf smb_bak.conf(备份源文件)

touch smb.conf

将下文复制进smb.conf中:

[gobal]

workgroup = LinuxSir

netbios name = RedHat

server string = Linux Samba Server

security = user

hosts allow = 192.168.1. 192.168.2. 127.

[public]

path = /XXXX/shareimg

writeable = yes

valid users = root

browseable = yes

guest ok = no

(public为访问时的路径名,path为系统实际路径)

文件配置介绍:

全局选项用于[global]的<section>选项定义中,其用于说明samba服务器的一些基本属性。其有些选项可以被其他<section>中的选项定义覆盖。

workgroup = MYGROUP

定义samba服务器所在的工作组或者域(如果设置security = domain的话)。

server string = Samba server

设定samba服务器的描述,通过网络邻居访问时可在备注中查看到该描述信息。

hosts allow = host (subnet)

设定允许访问该samba服务器的主机IP或网络,该选项的值为列表类型,不同的项目之间使用空格或逗号隔开,例如hosts allow = 192.168.3.0, 192.168.1.1,该选项设置允许主机192.168.1.1以及子网192.168.3.0/24内的所有主机访问该samba服务器。

hosts deny = host (subnet)

设定不允许访问该samba服务器的主机IP或网络,其格式与hosts allow一样。

guest account = guest

设定了游客的账号,在游客访问guest ok = yes的共享服务时,samba服务器将设置客户端以该游客账号来访问共享。

log file = MYLOGFILE

设定记录文件的位置。

max log size = size

设定记录文件的大小,单位为KB,如果设置为0则表示无大小限制。

security =

设定samba服务器的安全级,其有四种安全级别:share、user、server和domain,默认为user。关于这四种安全级别的详细信息,请查看相关文档。

password server = ServerIP

设定了用户账号认证服务器IP,其在设定security = server时有效。

encrypt passwords = yes | no

设定是否对密码进行加密。如果不对密码进行加密的话,在认证会话期间,客户端与服务器传递的是明文密码。但有些Windows系统默认情况下,不支持明文密码传输。

passdb backend = smbpasswd | tdbsam | ldapsam

设定samba服务器访问和存储samba用户账号的后端,在samba-3.0。23之前的默认值为smbpasswd,而之后的默认值为tdbsam。

smb passwd file =

设定samba的用户账号文件。对于源代码安装的samba,在samba-3.0.23之前,其默认值为/user/local/samba /private/smbpasswd;而samba-3.0.23之后,其默认值为/usr/local/samba/private /passwd.tdb。

include = smbconfFile

通过include选项可以包含其他配置文件,通过该选项和一些samba定义的变量可以设定与不同机器相关的配置。

local master = yes | no

设定该samba服务器是否试图成为本地主浏览器,默认值为yes。若设置为no,则该samba服务器永远不可能成为本地主浏览器,而设置为yes不代表其一定能成为本地主浏览器,只是让其能参与本地主浏览器的选举。

os level = N

N是一个整数,设定了该samba服务器参加本地主浏览器选举时的权重,其值越大,权重越大。os level = 0时,该服务器将失去选举的机会。

domain master = yes | no

设定samba服务器成为域浏览器。域浏览器从各个本地主浏览器处获取浏览列表,并将整个域的浏览列表传递给各个本地主浏览器。

preferred master = yes | no

设定该samba服务器是否为工作组里的首要主浏览器,如果设置为yes,则在nmbd启动时,将强制一个浏览选择。

局部选项:

局部选项为除了global外的各个<section>中的参数。其定义了共享服务的属性。

comment =

设定共享服务的描述信息。

path =

设定共享服务的路径,其中可以结合samba预定义的变量来设置。

hosts allow = host(subnet)

hosts deny = host(subnet)

与全局的hosts allow和hosts deny含义相同,其会覆盖全局的设置。

read only = yes | no

设定该共享服务是否为只读,该选项有一个同义选项writeable。

user = user(@group)

设定所有可能使用该共享服务的用户,可以使用@group来设置群组group中的所有用户账号。该选项的值为列表,不同的项目之间使用空格或逗号 隔开。在设置security = share时,客户端要访问某共享服务时提供的密码会与该选项指定的所有用户进行一一配对认证,若某用户认证通过,则以该用户权限进行共享服务访问,否则 拒绝客户端的访问(设置security = share不是允许游客访问,只有guest ok = yes才是允许游客访问,切记!!!)。

valid users = user(@group)

设定能够使用该共享服务的用户和组,其值的格式与user选项一样。

invalid users = user(@group)

设定不能够使用该共享服务的用户和组,其值的格式与user选项一样。

read list = user(@group)

设定对该共享服务只有读取权限的用户和组,其值的格式与user选项一样。

write list = user(@group)

设定对该共享服务拥有读写权限的用户和组,其值的格式与user选项一样。

admin list = user(@group)

设定对该共享服务拥有管理权限的用户和组,其值的格式与user选项一样。

public = yes | no

设定该共享服务是否能够被游客访问,其同义选项有guest ok。

create mode = mode

mode为八进制值,如0755,其默认值为0744。该选项指定的值用于过滤新建文件的访问权限,新建文件的默认权限将与create mode指定的值进行按位与操作,将结果再与force create mode指定的值进行按位或操作,得到的结果即为新建文件的访问权限。

force create mode = mode

mode为八进制值,默认为0000。其作用参考选项create mode。

directory mode = mode

mode为八进制值,默认为0755。该选项指定的值用于过滤新建目录的访问权限,新建目录的默认权限将与directory mode指定的值进行按位与操作,将结果再与force directory mode指定的值进行按位或操作,得到的结果即为新建目录的访问权限。

force directory mode = mode

mode为八进制值,默认为0000。该选项的作用参考选项directory mode。

force user = user

强制设定新建文件的属性onwer。若存在一个目录,其允许guest可以写,则guest就可以删除。但设定force user为其他用户,并设置create mode = 0755,则gues用户不能够删除其新建文件。

三.新建共享目录

#mkdir /XXXX/shareimg

#chmod 777 /XXXX/shareimg //让所有用户具有完全权限(默认用户为root)

四.将root用户加入smb的用户列表中

#smbpasswd –a root  //将root用户添加为samba用户,需设置访问密码

或者可以新建一个用户

#useradd cc   //添加cc用户

#passwd cc   //设置cc用户的口令

如果用新用户,需修改共享文件夹所有者

chown -R cc.cc /XXXX/shareimg

并且修改smb.conf中的valid users = cc

#smbpasswd –a cc  //将cc用户添加为samba用户,需设置访问密码

五.启动服务

设置开机自启动:

chkconfig --level 2345 smb on

chkconfig --level 2345 nmb on

service smb start

service nmb start

在下面问题修复后请重启服务:

service smb restart

service nmb restart

另:需在开机启动脚本/etc/rc.d/init.d/smb下添加一句话来防止启动服务时无法访问文件夹

……………

start() {

KIND="SMB"

echo -n $"Starting $KIND services: "

    setenforce 0  (加上此句)

daemon smbd $SMBDOPTIONS

RETVAL=$?

echo

[ $RETVAL -eq 0 ] && touch /var/lock/subsys/smb || \

RETVAL=1

return $RETVAL

}

…………

开机自启动存在问题!!!

六.连接

Windows下:\\ip地址\public

七.问题

(1)可以登录samba服务器,但是没有权限访问linux下的共享目录

1、确保linux下防火墙关闭或者是开放共享目录权限  iptalbes -F
2、确保samba服务器配置文件smb.conf设置没有问题,可网上查阅资料看配置办法
3、确保setlinux关闭,可以用setenforce 0命令执行。
默认的,SELinux禁止网络上对Samba服务器上的共享目录进行写操作,即使你在smb.conf中允许了这项操作。

这两个命令必须执行:

iptables -F

setenforce 0

(2)windows 删除共享缓存

C:\Documents and Settings\Administrator>net use
会记录新的网络连接。

状态       本地        远程    
                 网络

-------------------------------------------------------------------------------
OK           Z:      
 \\192.168.31.85\chrishome Microsoft Windows Network
OK                    
\\192.168.31.88\dev-home  Microsoft Windows Network
命令成功完成。

C:\Documents and Settings\Administrator>net use \\192.168.31.88\dev-home
/delete

\\192.168.31.88\dev-home 已经删除。

八.基于SMB/JCIFS协议的共享文件上传和下载(用于测试)

 package com.smb;

 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; public class Smbtest {
/**
* 从局域网*享文件中得到文件并保存在本地磁盘上
* @param remoteUrl 共享电脑路径 如:smb//administrator:123456@172.16.10.136/smb/1221.zip , smb为共享文件
* 注:如果一直出现连接不上,有提示报错,并且错误信息是 用户名活密码错误 则修改共享机器的文件夹选项 查看 去掉共享简单文件夹的对勾即可。
* @param localDir 本地路径 如:D:/
*/
public static void smbGet(String remoteUrl,String localDir){
InputStream in = null;
OutputStream out = null;
try {
SmbFile smbFile = new SmbFile(remoteUrl);
String fileName = smbFile.getName();
File localFile = new File(localDir+File.separator+fileName);
in = new BufferedInputStream(new SmbFileInputStream(smbFile));
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();
}
}
}
/**
* 把本地磁盘中的文件上传到局域网共享文件下
* @param remoteUrl 共享电脑路径 如:smb//administrator:123456@172.16.10.136/smb
* @param localFilePath 本地路径 如:D:/
*/
public static void smbPut(String remoteUrl,String localFilePath){
InputStream in = null;
OutputStream out = null;
try {
File localFile = new File(localFilePath);
String fileName = localFile.getName();
SmbFile remoteFile = new SmbFile(remoteUrl+"/"+fileName);
in = new BufferedInputStream(new FileInputStream(localFile));
out = new BufferedOutputStream(new SmbFileOutputStream(remoteFile));
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();
}
}
} public static void main(String[] args) {
smbPut("smb://root:smb@192.168.2.188/public", "E:/img/11.tmp");
smbGet("smb://root:smb@192.168.2.188/public/1.jpg ", "E:/"); } }

九.Web服务器访问外部文件夹

Jsp:

 <h1>请求图片</h1>

     <form name="userForm3" action="http://localhost:8080/naxincameraserver-war/userInfo/showPic"   enctype="multipart/form-data" method="post">

         <input type="text" name="pic" /><br/>

         <input type="submit" value="上传">

     </form>

Servlet:

Action中:(springMVC+spring+mybatis)

     @RequestMapping(value="/showPic",method = RequestMethod.POST)

     @ResponseBody

     public void showPicture(HttpServletRequest request,HttpServletResponse response){

         String url = request.getParameter("pic");

         System.out.println(url+"------------");

         response.setContentType("image/jpg"); //设置返回的文件类型

         try {

             OutputStream toClient=response.getOutputStream();

             SmbFiles.smbGet(url, "E:/",toClient);

         } catch (IOException e) {

             // TODO Auto-generated catch block

             e.printStackTrace();

         }

     }

修改Smbtest类:

 /**

      * 从局域网*享文件中得到文件并保存在本地磁盘上

      * @param remoteUrl 共享电脑路径 如:smb//administrator:123456@172.16.10.136/smb/1221.zip  , smb为共享文件

      * 注:如果一直出现连接不上,有提示报错,并且错误信息是 用户名活密码错误 则修改共享机器的文件夹选项 查看 去掉共享简单文件夹的对勾即可。

      * @param localDir 本地路径 如:D:/

      */ 

     public static void smbGet(String remoteUrl,String localDir,OutputStream toClient){ 

         InputStream in = null; 

         OutputStream out = null; 

         try { 

             SmbFile smbFile = new SmbFile(remoteUrl); 

             String fileName = smbFile.getName(); 

             File localFile = new File(localDir+File.separator+fileName); 

             in = new BufferedInputStream(new SmbFileInputStream(smbFile)); 

             out = new BufferedOutputStream(new FileOutputStream(localFile)); 

             byte []buffer = new byte[1024]; 

             while((in.read(buffer)) != -1){ 

                 out.write(buffer);

                 toClient.write(buffer);

                 buffer = new byte[1024]; 

             }

         } catch (Exception e) { 

             e.printStackTrace(); 

         }finally{ 

             try { 

                 out.close(); 

                 in.close();

                 toClient.close();

             } catch (IOException e) { 

                 e.printStackTrace(); 

             } 

         }

     }