Java连接服务器的两种方式SFTP和FTP
  yXrgnj2AQg6w 2023年11月08日 28 0

https://www.jb51.net/article/276407.htm

在项目开发中,一般文件存储很少再使用SFTP服务,但是也不排除合作伙伴使用SFTP来存储项目中的文件或者通过SFTP来实现文件数据的交互,这篇文章主要介绍了Java集成FTP与SFTP连接池

目录

  • 区别
  • FtpUtil
  • SFTPUtil
  • 问题


区别

FTP是一种文件传输协议,一般是为了方便数据共享的。包括一个FTP服务器和多个FTP客户端。FTP客户端通过FTP协议在服务器上下载资源。FTP客户端通过FTP协议在服务器上下载资源。而一般要使用FTP需要在服务器上安装FTP服务。

而SFTP协议是在FTP的基础上对数据进行加密,使得传输的数据相对来说更安全,但是传输的效率比FTP要低,传输速度更慢(不过现实使用当中,没有发现多大差别)。SFTP和SSH使用的是相同的22端口,因此免安装直接可以使用。

总结:

一;FTP要安装,SFTP不要安装。

二;SFTP更安全,但更安全带来副作用就是的效率比FTP要低。


FtpUtil

1

2

3

4

5

6


<

dependency

>


<

groupId

>commons-net

groupId

>


<

artifactId

>commons-net

artifactId

>


<

version

>3.6

version

>


dependency

>

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

import

org.apache.commons.net.ftp.FTP;

import

org.apache.commons.net.ftp.FTPClient;

import

org.apache.commons.net.ftp.FTPFile;

import

org.apache.commons.net.ftp.FTPReply;

import

org.slf4j.Logger;

import

org.slf4j.LoggerFactory;

import

org.springframework.beans.factory.annotation.Value;

import

org.springframework.stereotype.Component;

import

java.io.*;

@Component

public

class

FtpUtil {


private

static

final

Logger logger = LoggerFactory.getLogger(FtpUtil.

class

);


//ftp服务器地址


@Value

(

"${ftp.server}"

)


private

String hostname;


//ftp服务器端口


@Value

(

"${ftp.port}"

)


private

int

port;


//ftp登录账号


@Value

(

"${ftp.userName}"

)


private

String username;


//ftp登录密码


@Value

(

"${ftp.userPassword}"

)


private

String password;


/**


* 初始化FTP服务器


*


* @return


*/


public

FTPClient getFtpClient() {


FTPClient ftpClient =

new

FTPClient();


ftpClient.setControlEncoding(

"UTF-8"

);


try

{


//设置连接超时时间


ftpClient.setDataTimeout(

1000

*

120

);


logger.info(

"连接FTP服务器中:"

+ hostname +

":"

+ port);


//连接ftp服务器


ftpClient.connect(hostname, port);


//登录ftp服务器


ftpClient.login(username, password);


// 是否成功登录服务器


int

replyCode = ftpClient.getReplyCode();


if

(FTPReply.isPositiveCompletion(replyCode)) {


logger.info(

"连接FTP服务器成功:"

+ hostname +

":"

+ port);


}

else

{


logger.error(

"连接FTP服务器失败:"

+ hostname +

":"

+ port);


closeFtpClient(ftpClient);


}


}

catch

(IOException e) {


logger.error(

"连接ftp服务器异常"

, e);


}


return

ftpClient;


}


/**


* 上传文件


*


* @param pathName    路径


* @param fileName    文件名


* @param inputStream 输入文件流


* @return


*/


public

boolean

uploadFileToFtp(String pathName, String fileName, InputStream inputStream) {


boolean

isSuccess =

false

;


FTPClient ftpClient = getFtpClient();


try

{


if

(ftpClient.isConnected()) {


logger.info(

"开始上传文件到FTP,文件名称:"

+ fileName);


//设置上传文件类型为二进制,否则将无法打开文件


ftpClient.setFileType(FTP.BINARY_FILE_TYPE);


//路径切换,如果目录不存在创建目录


if

(!ftpClient.changeWorkingDirectory(pathName)) {


boolean

flag =

this

.changeAndMakeWorkingDir(ftpClient, pathName);


if

(!flag) {


logger.error(

"路径切换(创建目录)失败"

);


return

false

;


}


}


//设置被动模式,文件传输端口设置(如上传文件夹成功,不能上传文件,注释这行,否则报错refused:connect)


ftpClient.enterLocalPassiveMode();


ftpClient.storeFile(fileName, inputStream);


inputStream.close();


ftpClient.logout();


isSuccess =

true

;


logger.info(fileName +

"文件上传到FTP成功"

);


}

else

{


logger.error(

"FTP连接建立失败"

);


}


}

catch

(Exception e) {


logger.error(fileName +

"文件上传异常"

, e);



}

finally

{


closeFtpClient(ftpClient);


closeStream(inputStream);


}


return

isSuccess;


}


/**


* 删除文件


*


* @param pathName 路径


* @param fileName 文件名


* @return


*/


public

boolean

deleteFile(String pathName, String fileName) {


boolean

flag =

false

;


FTPClient ftpClient = getFtpClient();


try

{


logger.info(

"开始删除文件"

);


if

(ftpClient.isConnected()) {


//路径切换


ftpClient.changeWorkingDirectory(pathName);


ftpClient.enterLocalPassiveMode();


ftpClient.dele(fileName);


ftpClient.logout();


flag =

true

;


logger.info(

"删除文件成功"

);


}

else

{


logger.info(

"删除文件失败"

);


}


}

catch

(Exception e) {


logger.error(fileName +

"文件删除异常"

, e);


}

finally

{


closeFtpClient(ftpClient);


}


return

flag;


}


/**


* 关闭FTP连接


*


* @param ftpClient


*/


public

void

closeFtpClient(FTPClient ftpClient) {


if

(ftpClient.isConnected()) {


try

{


ftpClient.disconnect();


}

catch

(IOException e) {


logger.error(

"关闭FTP连接异常"

, e);


}


}


}


/**


* 关闭文件流


*


* @param closeable


*/


public

void

closeStream(Closeable closeable) {


if

(

null

!= closeable) {


try

{


closeable.close();


}

catch

(IOException e) {


logger.error(

"关闭文件流异常"

, e);


}


}


}


/**


* 路径切换(没有则创建)


*


* @param ftpClient FTP服务器


* @param path      路径


*/


public

void

changeAndMakeWorkingDir(FTPClient ftpClient, String path) {


boolean

flag =

false

;


try

{


String[] path_array = path.split(

"/"

);


for

(String s : path_array) {


boolean

b = ftpClient.changeWorkingDirectory(s);


if

(!b) {


ftpClient.makeDirectory(s);


ftpClient.changeWorkingDirectory(s);


}


}


flag =

true

;


}

catch

(IOException e) {


logger.error(

"路径切换异常"

, e);


}


return

flag;


}


/**


* 从FTP下载到本地文件夹


*


* @param ftpClient      FTP服务器


* @param pathName       路径


* @param targetFileName 文件名


* @param localPath      本地路径


* @return


*/


public

boolean

downloadFile(FTPClient ftpClient, String pathName, String targetFileName, String localPath) {


boolean

flag =

false

;


OutputStream os =

null

;


try

{


System.out.println(

"开始下载文件"

);


//切换FTP目录


ftpClient.changeWorkingDirectory(pathName);


ftpClient.enterLocalPassiveMode();


FTPFile[] ftpFiles = ftpClient.listFiles();


for

(FTPFile file : ftpFiles) {


String ftpFileName = file.getName();


if

(targetFileName.equalsIgnoreCase(ftpFileName)) {


File localFile =

new

File(localPath + targetFileName);


os =

new

FileOutputStream(localFile);


ftpClient.retrieveFile(file.getName(), os);


os.close();


}


}


ftpClient.logout();


flag =

true

;


logger.info(

"下载文件成功"

);


}

catch

(Exception e) {


logger.error(

"下载文件失败"

, e);


}

finally

{


closeFtpClient(ftpClient);


closeStream(os);


}


return

flag;


}

}


SFTPUtil

1

2

3

4

5

<

dependency

>


<

groupId

>com.jcraft

groupId

>


<

artifactId

>jsch

artifactId

>


<

version

>0.1.54

version

>


dependency

>

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

import

com.jcraft.jsch.*;

import

org.slf4j.Logger;

import

org.slf4j.LoggerFactory;

import

org.springframework.stereotype.Component;

import

java.io.File;

import

java.io.FileNotFoundException;

import

java.io.FileOutputStream;

import

java.io.InputStream;

import

java.util.Properties;

import

java.util.Vector;

@Component

public

class

SFTPUtil {


private

static

final

Logger logger = LoggerFactory.getLogger(SFTPUtil.

class

);


private

Session session =

null

;


private

ChannelSftp channel =

null

;


private

int

timeout =

60000

;


/**


* 连接sftp服务器


*/


public

boolean

connect(String ftpUsername, String ftpAddress,

int

ftpPort, String ftpPassword) {


boolean

isSuccess =

false

;


if

(channel !=

null

) {


System.out.println(

"通道不为空"

);


return

false

;


}


//创建JSch对象


JSch jSch =

new

JSch();


try

{


// 根据用户名,主机ip和端口获取一个Session对象


session = jSch.getSession(ftpUsername, ftpAddress, ftpPort);


//设置密码


session.setPassword(ftpPassword);


Properties config =

new

Properties();


config.put(

"StrictHostKeyChecking"

,

"no"

);


//为Session对象设置properties


session.setConfig(config);


//设置超时


session.setTimeout(timeout);


//通过Session建立连接


session.connect();


System.out.println(

"Session连接成功"

);


// 打开SFTP通道


channel = (ChannelSftp) session.openChannel(

"sftp"

);


// 建立SFTP通道的连接


channel.connect();


System.out.println(

"通道连接成功"

);


isSuccess =

true

;


}

catch

(JSchException e) {


logger.error(

"连接服务器异常"

, e);


}


return

isSuccess;


}


/**


* 关闭连接


*/


public

void

close() {


//操作完毕后,关闭通道并退出本次会话


if

(channel !=

null

&& channel.isConnected()) {


channel.disconnect();


}


if

(session !=

null

&& session.isConnected()) {


session.disconnect();


}


}


/**


* 文件上传


* 采用默认的传输模式:OVERWRITE


* @param src      输入流


* @param dst      上传路径


* @param fileName 上传文件名


*


* @throws SftpException


*/


public

boolean

upLoadFile(InputStream src, String dst, String fileName)

throws

SftpException {


boolean

isSuccess =

false

;


try

{


if

(createDir(dst)) {


channel.put(src, fileName);


isSuccess =

true

;


}


}

catch

(SftpException e) {


logger.error(fileName +

"文件上传异常"

, e);


}


return

isSuccess;


}


/**


* 创建一个文件目录


*


* @param createpath  路径


* @return


*/


public

boolean

createDir(String createpath) {


boolean

isSuccess =

false

;


try

{


if

(isDirExist(createpath)) {


channel.cd(createpath);


return

true

;


}


String pathArry[] = createpath.split(

"/"

);


StringBuffer filePath =

new

StringBuffer(

"/"

);


for

(String path : pathArry) {


if

(path.equals(

""

)) {


continue

;


}


filePath.append(path +

"/"

);


if

(isDirExist(filePath.toString())) {


channel.cd(filePath.toString());


}

else

{


// 建立目录


channel.mkdir(filePath.toString());


// 进入并设置为当前目录


channel.cd(filePath.toString());


}


}


channel.cd(createpath);


isSuccess =

true

;


}

catch

(SftpException e) {


logger.error(

"目录创建异常!"

, e);


}


return

isSuccess;


}


/**


* 判断目录是否存在


* @param directory     路径


* @return


*/


public

boolean

isDirExist(String directory) {


boolean

isSuccess =

false

;


try

{


SftpATTRS sftpATTRS = channel.lstat(directory);


isSuccess =

true

;


return

sftpATTRS.isDir();


}

catch

(Exception e) {


if

(e.getMessage().toLowerCase().equals(

"no such file"

)) {


isSuccess =

false

;


}


}


return

isSuccess;


}


/**


* 重命名指定文件或目录


*


*/


public

boolean

rename(String oldPath, String newPath) {


boolean

isSuccess =

false

;


try

{


channel.rename(oldPath, newPath);


isSuccess =

true

;


}

catch

(SftpException e) {


logger.error(

"重命名指定文件或目录异常"

, e);


}


return

isSuccess;


}


/**


* 列出指定目录下的所有文件和子目录。


*/


public

Vector ls(String path) {


try

{


Vector vector = channel.ls(path);


return

vector;


}

catch

(SftpException e) {


logger.error(

"列出指定目录下的所有文件和子目录。"

, e);


}


return

null

;


}


/**


* 删除文件


*


* @param directory  linux服务器文件地址


* @param deleteFile 文件名称


*/


public

boolean

deleteFile(String directory, String deleteFile) {


boolean

isSuccess =

false

;


try

{


channel.cd(directory);


channel.rm(deleteFile);


isSuccess =

true

;


}

catch

(SftpException e) {


logger.error(

"删除文件失败"

, e);


}


return

isSuccess;


}


/**


* 下载文件


*


* @param directory    下载目录


* @param downloadFile 下载的文件


* @param saveFile     下载到本地路径


*/


public

boolean

download(String directory, String downloadFile, String saveFile) {


boolean

isSuccess =

false

;


try

{


channel.cd(directory);


File file =

new

File(saveFile);


channel.get(downloadFile,

new

FileOutputStream(file));


isSuccess =

true

;


}

catch

(SftpException e) {


logger.error(

"下载文件失败"

, e);


}

catch

(FileNotFoundException e) {


logger.error(

"下载文件失败"

, e);


}


return

isSuccess;


}

}


问题

文件超出默认大小

#单文件上传最大大小,默认1Mbspring.http.multipart.maxFileSize=100Mb#多文件上传时最大大小,默认10Mbspring.http.multipart.maxRequestSize=500MB

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  2Vtxr3XfwhHq   2024年05月17日   53   0   0 Java
  Tnh5bgG19sRf   2024年05月20日   107   0   0 Java
  8s1LUHPryisj   2024年05月17日   46   0   0 Java
  aRSRdgycpgWt   2024年05月17日   47   0   0 Java
yXrgnj2AQg6w