最近在帮同学做一个音乐推荐系统后台,需要java远程调用Linux服务器,执行深度学习算法,处理由本地上传的文件。查找了相关的资料,利用ftpClient上传文件到服务器。在此贴一下这个助手类(网上很多)。
import org.apache.commons.lang.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import java.io.*;
/**
* JAVA FTPClient 工具类
*
* commons-net-1.4.1.jar PFTClinet jar包
*
* @author : hpp
*/
public class FtpClientUtils{
/**
* Description: 向FTP服务器上传文件
* @Version1.0
* @param url FTP服务器hostname
* @param port FTP服务器端口
* @param username FTP登录账号
* @param password FTP登录密码
* @param path FTP服务器保存目录
* @param filename 上传到FTP服务器上的文件名
* @param input 输入流
* @return 成功返回true,否则返回false
*/
public static boolean uploadFile(
String url,//FTP服务器hostname
int port,//FTP服务器端口
String username, // FTP登录账号
String password, //FTP登录密码
String path, //FTP服务器保存目录
String filename, //上传到FTP服务器上的文件名
InputStream input // 输入流
) {
boolean success = false;
FTPClient ftp = new FTPClient();
try {
int reply;
ftp.connect(url, port);//连接FTP服务器
//如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
ftp.login(username, password);//登录
reply = ftp.getReplyCode();
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
System.out.println("FTP服务器 拒绝连接");
return success;
}
ftp.changeWorkingDirectory(path);
ftp.storeFile(filename, input);
input.close();
ftp.logout();
success = true;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
return success;
}
/**
* 删除文件
* @param fileName 要删除的文件地址
* @return true/false
* @throws IOException
*/
public static boolean delete(String fileName, FTPClient ftpClient) throws IOException {
return ftpClient.deleteFile(fileName);
}
/**
* 下载文件到指定目录
* @param ftpFile 文件服务器上的文件地址
* @param dstFile 输出文件的路径和名称
* @throws Exception
*/
public static void downLoad(String ftpFile, String dstFile, FTPClient ftpClient) throws Exception {
if (StringUtils.isBlank(ftpFile)) {
throw new RuntimeException("ftpFile为空");
}
if (StringUtils.isBlank(dstFile)) {
throw new RuntimeException("dstFile为空");
}
File file = new File(dstFile);
FileOutputStream fos = new FileOutputStream(file);
ftpClient.retrieveFile(ftpFile, fos);
fos.flush();
fos.close();
}
/**
* 从文件服务器获取文件流
* @param ftpFile 文件服务器上的文件地址
* @return {@link InputStream}
* @throws IOException
*/
public static InputStream retrieveFileStream(String ftpFile, FTPClient ftpClient) throws IOException {
if (StringUtils.isBlank(ftpFile)) {
throw new RuntimeException("ftpFile为空");
}
return ftpClient.retrieveFileStream(ftpFile);
}
public static void main(String[] args) {
try {
FileInputStream in=new FileInputStream(new File("F:\\istep\\istep\\src\\main\\webapp\\recordFiles\\333.mp3"));
boolean flag = uploadFile("XXX.XXX.XXX.XXX", 21, "userName", "password", "/home/tomcat-istep-8787/webapps/istep/videoPlay/", "333.mp3", in);
System.out.println(flag);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
原因是:root账号没有上传文件的权限。
解决方法:http://blog.csdn.net/chuweiguo789/article/details/44015529
============以下转载自:http://blog.csdn.net/chuweiguo789/article/details/44015529 ===================
1:先看 Linux服务器的防火墙关了 没。service iptables stop 关闭防火墙。这算一个错误。
2:若是防火墙关了,还报此错误。你可以继续排查。看 linux是否有ftp服务 。
你可以使用 service vsftpd status 来查看ftp是否开启。(vsftpd is running...,是说明目前ftp是开启状态),chkconfig --list vsftpd 也是查看ftp服务是否开启(netstat -tnl也可以查询21端口是否开启)。
也可以使用ps -ef | grep ftp 来查看本地是否含有包含ftp的进程开启。(看ftp22端口是否使用)。
总之第二个原因就是服务器是否有ftp服务。若没有你要自己安装ftp服务器,若有,而是没有启动你可以启动ftp服务(使用service vsftpd start 启动 或者 service vsftpd restart 重启)。
(三):就是你连接上了,只是ftpClient.getReplyCode()的返回值是530,那么就是因为你当前用户没有传输文件的权限,先提供如下解决办法。
一般root用户是有权限的若是root还返回530,就用一下方法:先查看/etc/vsftpd/下面的文件ftpusers和user_list里面是否有你的用户名,若有注释就可以了。这两个文件中的用户都是没有权限。(我就是这么解决的)
给用户添加ftp权限:以下步骤是在网上搜的没有亲测,大家可以试试。
在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服务器
[root@linuxsir001 root]# /etc/init.d/vsftpd restart
5、如果需要允许用户修改密码,但是又没有telnet登录系统的权限:
usermod -s /usr/bin/passwd test //用户telnet后将直接进入改密界面
看到230,恭喜你。总算大功告成了!!!哎、、、不容易哈!
最后附上ftpClient.getReplyCode()的返回值的对应信息:
110 重新启动标记应答。在这种情况下文本是确定的,它必须是:MARK yyyy=mmmm,其中yyyy是用户进程数据流标记,mmmm是服务器标记。
120 服务在nnn分钟内准备好
125 数据连接已打开,准备传送
150 文件状态良好,打开数据连接
200 命令成功
202 命令未实现
211 系统状态或系统帮助响应
212 目录状态
213 文件状态
214 帮助信息,信息仅对人类用户有用
215 名字系统类型
220 对新用户服务准备好
221 服务关闭控制连接,可以退出登录
225 数据连接打开,无传输正在进行
226 关闭数据连接,请求的文件操作成功
227 进入被动模式
230 用户登录
250 请求的文件操作完成
257 创建 "PATHNAME "
331 用户名正确,需要口令
332 登录时需要帐户信息
350 请求的文件操作需要进一步命令
421 不能提供服务,关闭控制连接
425 不能打开数据连接
426 关闭连接,中止传输
450 请求的文件操作未执行
451 中止请求的操作:有本地错误
452 未执行请求的操作:系统存储空间不足
500 格式错误,命令不可识别
501 参数语法错误
502 命令未实现
503 命令顺序错误
504 此参数下的命令功能未实现
530 未登录(用户名或密码错误,1、FTP密码修改了?2、用户名/密码输入错误?先仔细检查有无输入错误 如复制的时候误复制了空格!!)
532 存储文件需要帐户信息
550 未执行请求的操作
551 请求操作中止:页类型未知
552 请求的文件操作中止,存储分配溢出
553 未执行请求的操作:文件名不合法