上传文件下载文件没有难度记录一下 ftp以前在网上找的不知道原作者 stfp为自己记录 建议使用stfp
STCP方式
方法 | 作用 |
---|---|
cd() | 进入指定目录 |
put() | 文件上传 |
get() | 文件下载 |
mkdir() | 创建目录 |
rmdir() | 删除目录 |
ls() | 获取当前目录文件列表 |
rename() | 文件或目录重命名 |
rm() | 删除文件 |
-
客户端文件上传到linux文件目录
-
解决中文名称下载到客户端乱码
<!-- sftp上传文件 -->
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.54</version>
</dependency>
使用SpringMVC Controller
@RequestMapping("file")
@Controller
public class FileUploadController {
private static final transient Logger LOGGER = LoggerFactory.getLogger(FileUploadController.class);
/** 上传文件 */
@PostMapping("upload")
@ResponseBody
public Map<String, Object> uploadFile(MultipartFile file) {
Map<String, Object> res = new HashMap<>();
Map<String, Object> resUrl = new HashMap<>();
try {
if (file != null) {
// 取得当前上传文件的文件名称
String fileName = file.getOriginalFilename();
// 如果名称不为"" 说明该文件存在 否则说明该文件不存在
if ("" != fileName.trim()) {
// 打印文件名称
LOGGER.info(">>> fileName <<<" + fileName);
// 获取扩展名
String fileExtName = fileName.substring(fileName.lastIndexOf("."));
// 没有'-'的uuid
String newFileName = UUID.randomUUID().toString().replace("-", "");
// 文件新名称
newFileName = newFileName + fileExtName;
InputStream is = file.getInputStream();
// linux服务器地址 账号 密码
ChannelSftp sftp = getChannel("192.168.25.25", 22, "root", "root", 60000);
final String folderName = "/usr/local/upload/";
// 进入linux服务器文件目录
sftp.cd(folderName);
// 判断子目录文件夹是否存在 不存在即创建
SftpATTRS attrs = sftp.stat(folderName);
if (attrs == null) {
sftp.mkdir(folderName);
LOGGER.info("创建目录 : " + folderName);
}
// 把文件流命名成文件名称推送到linux
sftp.put(is, newFileName);
closeChannel(); // 关闭连接
resUrl.put("src", newFileName);
res.put("data", resUrl);
System.out.println(res.toString());
return res;
}
}
} catch (Exception e) {
LOGGER.error("上传文件失败 请检查连接参数", e);
}
res.put("code", 1);
res.put("msg", "");
LOGGER.info(res.toString());
return res;
}
/** 下载文件 要下载的文件名 下载到客户端文件名 方法不可有返回值 */
@GetMapping("download")
public void downloadFile(String fileName, String localFileName,
HttpServletRequest request, HttpServletResponse response) {
// 不传客户端本地文件名称 则使用服务器上的名称
if (null != localFileName && !"".equals(localFileName.trim())) {
// 使用客户端传递的名称 + 服务器上的文件后缀名
localFileName += fileName.substring(fileName.lastIndexOf("."));
} else {
localFileName = fileName;
}
// 获得请求头中的User-Agent
String agent = request.getHeader("User-Agent");
// 根据不同浏览器进行不同的编码 把中文名称转成ISO8859-1解决乱码
try {
// 解决中文文件名乱码问题 firefox 和 chrome 解码相同
if (agent.toLowerCase().indexOf("firefox") > 0 || agent.toUpperCase().indexOf("CHROME") > 0) {
localFileName = new String(localFileName.getBytes("UTF-8"), "ISO8859-1");
} else if (agent.toUpperCase().indexOf("MSIE") > 0) {
localFileName = URLEncoder.encode(localFileName, "UTF-8"); // IE浏览器采用URL编码
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
LOGGER.info("fileName : " + fileName);
if (fileName != null && !"".equals(fileName.trim())) {
response.setContentType("application/force-download"); // 设置强制下载不打开
response.addHeader("Content-Disposition", "attachment;fileName=" + localFileName); // 设置文件名
ChannelSftp sftp = null;
try {
// linux服务器地址 账号 密码
sftp = getChannel("192.168.10.10", 22, "root", "root", 60000);
// 获得输出流 通过response获得的输出流 用于向客户端写内容
ServletOutputStream out = response.getOutputStream();
// 获取输出流 并自动输出到客户端 路径名 + 文件名
sftp.get("/data/upload/upload-files/" + fileName, out);
out.close(); // 关闭输出流
} catch (Exception e) {
e.printStackTrace();
} finally {
sftp.quit(); // 退出连接
closeChannel(); // 关闭连接资源
}
}
}
Session session = null;
Channel channel = null;
/**
* 使用SFTP方法
* @param ftpHost ip地址
* @param ftpPort 端口
* @param ftpUserName 用户名
* @param ftpPassword 密码
* @param timeout 超时时间
* @return
* @throws JSchException
*/
private ChannelSftp getChannel(String ftpHost, int ftpPort, String ftpUserName, String ftpPassword, int timeout) throws JSchException {
JSch jsch = new JSch(); // 创建JSch对象
// 根据用户名 主机ip 端口获取一个Session对象
session = jsch.getSession(ftpUserName, ftpHost, ftpPort);
LOGGER.debug("Session created");
session.setPassword(ftpPassword); // 设置密码
Properties config = new Properties();
// 连接新主机时 不进行公钥确认 避免IP地址的公钥改变不可连接
config.put("StrictHostKeyChecking", "no");
session.setConfig(config); // 为Session对象设置properties
session.setTimeout(timeout); // 设置timeout时间
// 超时时间 可不设置时间
session.connect(1500); // 通过Session建立链接
LOGGER.debug("Session connected");
channel = session.openChannel("sftp"); // 打开SFTP通道
LOGGER.debug("Opening Channel");
channel.connect(); // 建立SFTP通道的连接
LOGGER.debug("ftpHost = " + ftpHost + ", ftpUserName = " + ftpUserName + ", returning: " + channel);
return (ChannelSftp) channel;
}
private void closeChannel() {
if (channel != null) {
channel.disconnect();
}
if (session != null) {
session.disconnect();
}
}
}
TCP方式 依赖commons-net包
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
@RequestMapping("file")
@Controller
public class FTPController {
private static final transient Logger LOGGER = LoggerFactory.getLogger(FTPController.class);
/** Description 从FTP服务器上传文件 */
@PostMapping("upload")
public String uploadFile(MultipartFile file) {
String fileName = file.getOriginalFilename();
InputStream inputStream = null;
try {
inputStream = file.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
FTPClient ftp = new FTPClient();
try {
int reply;
ftp.connect("192.168.25.25", 22); // 连接FTP服务器
//如果采用默认端口 可以使用ftp.connect(url)的方式直接连接FTP服务器
ftp.login("root", "root"); // 登录
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
LOGGER.info("上传文件失败");
}
ftp.changeWorkingDirectory(filePath);
ftp.storeFile(fileName, inputStream);
inputStream.close();
ftp.logout();
LOGGER.info("上传文件成功");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return fileName;
}
/** Description 从FTP服务器下载文件 */
public static void downFile(String fileName, String localFileName
, HttpServletRequest request, HttpServletResponse response) {
FTPClient ftp = new FTPClient();
// 获得请求头中的User-Agent
String agent = request.getHeader("User-Agent");
// 根据不同浏览器进行不同的编码 把中文名称转成ISO8859-1解决乱码
try {
// 解决中文文件名乱码问题 firefox 和 chrome 解码相同
if (agent.toLowerCase().indexOf("firefox") > 0 || agent.toUpperCase().indexOf("CHROME") > 0) {
localFileName = new String(localFileName.getBytes("UTF-8"), "ISO8859-1");
} else if (agent.toUpperCase().indexOf("MSIE") > 0) {
localFileName = URLEncoder.encode(localFileName, "UTF-8"); // IE浏览器采用URL编码
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
try {
int reply;
ftp.connect("192.168.25.25", 22);
//如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
ftp.login("root", "root");//登录
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
LOGGER.info("下载文件失败");
}
ftp.changeWorkingDirectory(filePath); // 进入到FTP服务器目录
FTPFile[] fs = ftp.listFiles();
for(FTPFile ff:fs){
if(ff.getName().equals(fileName)){
// 获得输出流 通过response获得的输出流 用于向客户端写内容
ServletOutputStream out = response.getOutputStream();
ftp.retrieveFile(ff.getName(), out);
out.close();
}
}
ftp.logout();
LOGGER.info("下载文件成功");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
}
}
```
***
java 无法连接ftp服务器(500 OOPS: cannot change directory)
在本地打开命令窗口 输入ftp ftp服务器IP 窗口提示输入用户名密码
在终端下输入如下命令
```shell
[root@liangwode log]# sestatus -b| grep ftp
allow_ftpd_anon_write off
allow_ftpd_full_access off
allow_ftpd_use_cifs off
allow_ftpd_use_nfs off
ftp_home_dir off
ftpd_connect_db off
ftpd_use_passive_mode off
httpd_enable_ftp_server off
tftp_anon_write off
```
ftp_home_dir为off的状态 即当前不允许用户通过FTP登录到/home/*(*代表对应的用户)的目录下
开启ftp_home_dir的功能
```shell
[root@liangwode log]# setsebool ftp_home_dir on
```
状态如下说明开启ftp_home_dir的功能成功
```shell
[root@liangwode log]# sestatus -b| grep ftp
allow_ftpd_anon_write off
allow_ftpd_full_access off
allow_ftpd_use_cifs off
allow_ftpd_use_nfs off
ftp_home_dir on
ftpd_connect_db off
ftpd_use_passive_mode off
httpd_enable_ftp_server off
tftp_anon_write off
```
***
linux ftp安装配置
使用yum命令安装ftp `# yum install vsftpd`
ftp服务的开启与关闭 `开启# service vsftpd start` `关闭# service vsftpd stop`
安装成功后 在本地使用ftp软件连接 默认账号和密码为linux的账号和密码
在linux中添加ftp用户 设置相应的权限
1 环境
ftp为vsftp 被限制用户名为test被限制路径为/home/test
2 建用户在root用户下
`# useradd -d /home/test test //增加用户test 并制定test用户的主目录为/home/test`
`# passwd test //为test设置密码`
3 更改用户相应的权限设置
`# usermod -s /sbin/nologin test //限定用户test不能telnet 只能ftp`
`# usermod -s /sbin/bash test //用户test恢复正常`
`# usermod -d /test test //更改用户test的主目录为/test`
4 限制用户只能访问/home/test 不能访问其他路径
修改 # /etc/vsftpd/vsftpd.conf 如下
`chroot_list_enable=YES //限制访问自身目录`
`# (default follows)`
`chroot_list_file=/etc/vsftpd/vsftpd.chroot_list`
编辑 vsftpd.chroot_list文件 将受限制的用户添加进去 每个用户名一行
改完配置文件 不要忘记重启vsFTPd服务器
`# /etc/init.d/vsftpd restart`
5 如果需要允许用户修改密码 但是又没有telnet登录系统的权限
`# usermod -s /usr/bin/passwd test //用户telnet后将直接进入改密界面`
linux ftp的安装与配置参考 https://www.cnblogs.com/yangjinjin/p/3158245.html