最近在做一个文件上传的子模块,总是出现一个问题,就是远程创建目录失败。

之前还在怀疑路径是否出问题了(我有一个习惯就是:目录的最后一个字符必定为”/“),可经过测试后,仍然无法成功创建目录。

然后跟踪源码,经过一番勘察后,最后调用的就是 FTP 的命令,发现并没有任何其他与路径有关系的。

最后想到了一个问题,ftpuser 是否具有该目录的写权限,最后进入服务器检查:

1
2
3
4
5
[root@bogon www]# ll
总用量 0
drwx------ 3 ftpuser ftpuser 17 4月 27 00:51 images
drwxr-xr-x 3 root root 58 6月 5 11:23 sources
drwxr-xr-x 4 root root 25 6月 2 11:04 std

果然是权限的问题,通过以下命令:

1
2
[root@bogon www]# chown -R ftpuser:ftpuser sources
[root@bogon www]# chown -R ftpuser:ftpuser std

最终问题解决

1
2
3
4
[root@bogon 9]# pwd
/home/ftpuser/www/sources/2/9
[root@bogon 9]# ls
5de87e8cca0044f6bfbc5b56a729d71f.cpp

最后上 使用 FTPClient 上传文件 的源码,当然这个源码存在诸多问题,反正我怎么看怎么不爽 ; )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/**
* Description: 向FTP服务器上传文件
*
* @param host
* FTP服务器hostname
* @param port
* FTP服务器端口
* @param username
* FTP登录账号
* @param password
* FTP登录密码
* @param basePath
* FTP服务器基础目录
* @param filePath
* FTP服务器文件存放路径。例如分日期存放:/2015/01/01。文件的路径为basePath+filePath
* @param filename
* 上传到FTP服务器上的文件名
* @param input
* 输入流
* @param type
* 上传文件类型
*
* @return 成功返回true,否则返回false
*
* @author JohnNiang
*/
public static boolean uploadFile(String host, int port,
String username, String password, String basePath,
String filePath, String filename, InputStream input, int type) {
boolean result = false;
FTPClient ftp = new FTPClient();
try {
int reply;
logger.info("开始连接ftp服务器,host: " + host + ", port: " + port);
ftp.connect(host, port);// 连接FTP服务器
// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
logger.info("登录ftp,username: " + username);
ftp.login(username, password);// 登录
reply = ftp.getReplyCode();
logger.info("ftp服务器回应: " + reply);
if (!FTPReply.isPositiveCompletion(reply)) {
logger.error("登录失败,正在断开连接");
ftp.disconnect();
return result;
}
logger.info("登录成功");
// 切换到上传目录
logger.debug("正在切换至目录: " + basePath + filePath);
if (!ftp.changeWorkingDirectory(basePath + filePath)) {
logger.info(basePath + filePath + "目录不存在,正在创建该目录");
// 如果目录不存在创建目录
String[] dirs = filePath.split("/");
String tempPath = basePath;
for (String dir : dirs) {
if (null == dir || "".equals(dir))
continue;
tempPath += dir + "/";
logger.debug("正在切换至" + tempPath + "目录");
if (!ftp.changeWorkingDirectory(tempPath)) {
logger.info(tempPath + "目录不存在,正在创建该目录");
if (!ftp.makeDirectory(tempPath)) {
logger.error("创建" + tempPath + "目录失败");
return result;
} else {
logger.debug("创建" + tempPath + "目录成功");
logger.debug("正在切换至" + tempPath + "目录");
ftp.changeWorkingDirectory(tempPath);
}
}
}
}
logger.debug("设置上传文件类型为: " + type);
ftp.setFileType(type);
logger.debug("正在上传" + filename + "文件");
// 上传文件
if (!ftp.storeFile(filename, input)) {
logger.error(filename + "上传失败");
return result;
}
logger.debug("ftp注销中...");
input.close();
ftp.logout();
result = true;
} catch (IOException e) {
logger.error("", e);
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
return result;
}