Java实现跨服务器上传文件功能

时间:2021-08-25 14:46:22

前几天做个项目,本身客户端和管理员端是写在一起的,共用一台服务器,客户上传的文件都是存在服务器的硬盘上的。老龙提出要把客户端和管理员端分离,这时候用户上传的附件的存储就出现问题了。显然,把大到几百M的apk文件存到数据库不现实,查了半天,在两端建立ftp服务器传文件是最快的方法。

具体流程是,用户登录外网客户端,上传文件到外网的服务器硬盘上,在此同时,文件通过外网服务器访问内网管理员服务器的ftp服务器,传到内网服务器的硬盘上。这样内网服务器可以对上传的文件进行加密签名工作,之后也通过ftp的方式把文件回传到外网服务器硬盘上,供用户进行其他操作。

具体实现时用到的工具:Serv-U。Serv-U是一个方便我们在windows上建立ftp服务器的工具。下载破解后,按照步骤,设置好Ip、端口、账户密码、允许ftp访问的磁盘路径、操作权限等,就可以使用了。IP在本机测试的时候就选127.0.0.1,内网测试时就选192.168.0.x。

在java项目中的实现,我自己写了个工具类,用到了apache的commons-net包,有上传,下载以及删除功能。附上代码:

?
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
package app.ftp;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
 
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
 
/**
 * FTP服务器工具类
 *
 */
public class FTPUtils {
   
  /**
   * 上传文件至FTP服务器
   *
   * @param url
   *   服务器IP地址
   * @param port
   *   服务器端口
   * @param userName
   *   用户登录名
   * @param password
   *   用户登录密码
   * @param storePath
   *   服务器文件存储路径
   * @param fileName
   *   服务器文件存储名称
   * @param is
   *   文件输入流
   * @return
   *   <b>true</b>:上传成功
   *   <br/>
   *   <b>false</b>:上传失败
   */
  public static boolean storeFile (String url, int port, String userName, String password, String storePath, String fileName, InputStream is) {
    boolean result = false;
    FTPClient ftp = new FTPClient();
    try {
      // 连接至服务器,端口默认为21时,可直接通过URL连接
      ftp.connect(url ,port);
      // 登录服务器
      ftp.login(userName, password);
      // 判断返回码是否合法
      if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
        // 不合法时断开连接
        ftp.disconnect();
        // 结束程序
        return result;
      }
      // 判断ftp目录是否存在,如果不存在则创建目录,包括创建多级目录
      String s = "/"+storePath;
      String[] dirs = s.split("/");
      ftp.changeWorkingDirectory("/");      
        //按顺序检查目录是否存在,不存在则创建目录 
        for(int i=1; dirs!=null&&i<dirs.length; i++) { 
          if(!ftp.changeWorkingDirectory(dirs[i])) { 
            if(ftp.makeDirectory(dirs[i])) { 
              if(!ftp.changeWorkingDirectory(dirs[i])) { 
                return false
              
            }else
              return false;             
            
          
        
      // 设置文件操作目录
      ftp.changeWorkingDirectory(storePath);
      // 设置文件类型,二进制
      ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
      // 设置缓冲区大小
      ftp.setBufferSize(3072);
      // 上传文件
      result = ftp.storeFile(fileName, is);
      // 关闭输入流
      is.close();
      // 登出服务器
      ftp.logout();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      try {
        // 判断输入流是否存在
        if (null != is) {
          // 关闭输入流
          is.close();
        }
        // 判断连接是否存在
        if (ftp.isConnected()) {
          // 断开连接
          ftp.disconnect();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return result;
  }
   
  /**
   * 从FTP服务器下载文件至本地
   *
   * @param url
   *   服务器IP地址
   * @param port
   *   服务器端口
   * @param userName
   *   用户登录名
   * @param password
   *   用户登录密码
   * @param remotePath
   *   服务器文件存储路径
   * @param fileName
   *   服务器文件存储名称
   * @param localPath
   *   本地文件存储路径
   * @return
   *   <b>true</b>:下载成功
   *   <br/>
   *   <b>false</b>:下载失败
   */
  public static boolean retrieveFile (String url, int port, String userName, String password, String remotePath, String fileName, String localPath) {
    boolean result = false;
    FTPClient ftp = new FTPClient();
    OutputStream os = null;
    try {
      // 连接至服务器,端口默认为21时,可直接通过URL连接
      ftp.connect(url ,port);
      // 登录服务器
      ftp.login(userName, password);
      // 判断返回码是否合法
      if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
        // 不合法时断开连接
        ftp.disconnect();
        // 结束程序
        return result;
      }
      // 设置文件操作目录
      ftp.changeWorkingDirectory(remotePath);
      // 设置文件类型,二进制
      ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
      // 设置缓冲区大小
      ftp.setBufferSize(3072);
      // 设置字符编码
      ftp.setControlEncoding("UTF-8");
      // 构造本地文件对象
      File localFile = new File(localPath + "/" + fileName);
      // 获取文件操作目录下所有文件名称
      String[] remoteNames = ftp.listNames();
      // 循环比对文件名称,判断是否含有当前要下载的文件名
      for (String remoteName: remoteNames) {
        if (fileName.equals(remoteName)) {
          result = true;
        }
      }
      // 文件名称比对成功时,进入下载流程
      if (result) {
        // 构造文件输出流
        os = new FileOutputStream(localFile);
        // 下载文件
        result = ftp.retrieveFile(fileName, os);
        // 关闭输出流
        os.close();
      }
      // 登出服务器
      ftp.logout();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      try {
        // 判断输出流是否存在
        if (null != os) {
          // 关闭输出流
          os.close();
        }
        // 判断连接是否存在
        if (ftp.isConnected()) {
          // 断开连接
          ftp.disconnect();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return result;
  }
   
  /**
   * 从FTP服务器删除文件
   *
   * @param url
   *   服务器IP地址
   * @param port
   *   服务器端口
   * @param userName
   *   用户登录名
   * @param password
   *   用户登录密码
   * @param remotePath
   *   服务器文件存储路径
   * @param fileName
   *   服务器文件存储名称
   * @return
   *   <b>true</b>:删除成功
   *   <br/>
   *   <b>false</b>:删除失败
   */
  public static boolean deleteFile (String url, int port, String userName, String password, String remotePath, String fileName) {
    boolean result = false;
    FTPClient ftp = new FTPClient();
    try {
      // 连接至服务器,端口默认为21时,可直接通过URL连接
      ftp.connect(url ,port);
      // 登录服务器
      ftp.login(userName, password);
      // 判断返回码是否合法
      if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
        // 不合法时断开连接
        ftp.disconnect();
        // 结束程序
        return result;
      }
      // 设置文件操作目录
      ftp.changeWorkingDirectory(remotePath);
      // 设置文件类型,二进制
      ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
      // 设置缓冲区大小
      ftp.setBufferSize(3072);
      // 设置字符编码
      ftp.setControlEncoding("UTF-8");
      // 获取文件操作目录下所有文件名称
      String[] remoteNames = ftp.listNames();
      // 循环比对文件名称,判断是否含有当前要下载的文件名
      for (String remoteName: remoteNames) {
        if (fileName.equals(remoteName)) {
          result = true;
        }
      }
      // 文件名称比对成功时,进入删除流程
      if (result) {
        // 删除文件
        result = ftp.deleteFile(fileName);
      }
      // 登出服务器
      ftp.logout();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      try {
        // 判断连接是否存在
        if (ftp.isConnected()) {
          // 断开连接
          ftp.disconnect();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return result;
  }  
 
   
  public static void main(String[] args) throws FileNotFoundException {
//   try {
//     FileInputStream fis = new FileInputStream(new File("D:/Soft Storage/软件工具箱/HTML_Help_WorkShop_1.3_XiaZaiBa.zip"));
//     System.out.println(storeFile("192.168.1.2", 21, "admin", "1", "C:/Documents and Settings/Administrator/桌面", RandomUUID.random() + ".zip", fis));
//   } catch (FileNotFoundException e) {
//     e.printStackTrace();
//   }
//   
    //File file = new File("C:/Users/freed/Desktop/1.txt");
    //InputStream is = new FileInputStream(file);
 
    //System.out.println(storeFile("127.0.0.1", 21, "feili", "feili", "examples", "2.txt", is));
    //System.out.println(retrieveFile("127.0.0.1", 21, "feili", "feili", "examples/jsp", "index.html", "C:/Users/freed/Desktop"));
    //System.out.println(deleteFile("127.0.0.1", 21, "feili", "feili", "testpath", "1.txt"));
 
  }
 
   
}

需要注意的是上传文件的时候要将File文件先放入fileinputstream中。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:http://blog.csdn.net/wu_fei_li/article/details/69949928