Java TCP和STCP文件上传和下载

上传文件下载文件没有难度记录一下 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

转载于:https://www.cnblogs.com/setlilei/p/11032359.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值