Java代码实现文件上传到Linux服务器 (java 文件上传到linux服务器端)
文件上传是在日常应用中非常常见的需要。在许多场合中,我们需要将某个文件传输到服务器上,以便在后续的操作中使用。这种文件上传的需求既可以采用传统的方法进行,比如使用FTP、SCP、SFTP协议等,也可以借助各种语言的网络上传库来实现。本文主要介绍如何使用的功能。
准备工作
在开始介绍具体的实现方式前,我们需要确保已经准备好以下的软件和环境:
– JDK 1.8以上版本。
– Linux服务器(Ubuntu、CentOS、Debian等)。
– 在Linux服务器上配置好SSH服务,并能够通过SSH连接到服务器。
– 在Java代码中引入Jsch库(Java Secure Channel)。
Jsch是一个Java Secure Channel(Java安全通道)的实现,可以提供一个安全通道来传输文件、执行命令等。在本文中,我们使用Jsch库来实现文件上传功能。
文件上传
在Java代码中导入Jsch的jar包。如果使用Maven,则在项目的pom.xml文件中添加如下依赖:
“`
com.jcraft
jsch
0.1.54
“`
接下来,我们开始编写Java代码。
1. 需要建立一个SSH连接。可以使用ch类来创建一个SSH连接,如下所示:
“`java
ch jsch = new ch();
Session session = jsch.getSession(username, host, port);
session.setPassword(password);
session.connect();
“`
其中,username和password分别表示Linux服务器的用户名和密码,host表示服务器的IP地址或者域名,port表示SSH连接的端口号。如果没有指定端口号,则默认为22。
2. 在建立SSH连接后,我们需要实现文件上传功能。在Linux服务器中,我们可以使用SCP协议来实现文件上传。SCP是Secure Copy Protocol(安全拷贝协议)的缩写,可以通过SSH通道安全地传输文件。在Java代码中,可以通过Session对象提供的功能来实现SCP上传。具体实现代码如下:
“`java
String src = “(本地文件路径)”;
String dest = “(服务器文件路径)”;
String command = “scp -p -t ” + dest;
Channel channel = session.openChannel(“exec”);
((ChannelExec) channel).setCommand(command);
OutputStream out = channel.getOutputStream();
InputStream in = channel.getInputStream();
channel.connect();
if (checkAck(in) != 0) {
System.exit(0);
}
File file = new File(src);
long filesize = file.length();
command = “C0644 ” + filesize + ” “;
if (src.lastIndexOf(“/”) > 0) {
command += src.substring(src.lastIndexOf(“/”) + 1);
} else {
command += src;
}
command += “\n”;
out.write(command.getBytes());
out.flush();
if (checkAck(in) != 0) {
System.exit(0);
}
FileInputStream fis = new FileInputStream(src);
byte[] buf = new byte[1024];
while (true) {
int len = fis.read(buf, 0, buf.length);
if (len
out.write(buf, 0, len);
}
fis.close();
out.flush();
command = “exit\n”;
out.write(command.getBytes());
out.flush();
channel.disconnect();
session.disconnect();
“`
在上述代码中,我们定义了两个变量src和dest,分别表示本地文件路径和服务器文件路径。这里采用的是绝对路径的方式。command变量用于定义SCP协议的传输命令,因为SCP协议的实现方式不同于常见的FTP、SFTP等文件传输协议,所以需要专门的传输命令。
在连接建立后,我们创建一个ChannelExec对象来执行SCP命令。然后使用getOutputStream方法获取输出流和getInputStream方法获取输入流。输入流主要用于监听SCP协议传输的反馈信息,输出流则用于写入文件内容。在while循环中,我们读取本地文件内容并通过输出流写入,直到文件传输完成。在我们发送一个退出命令,关闭Channel对象并结束SSH连接。
在上述的实现中,我们还需要实现一个方法用于监听SCP协议的传输反馈信息,如果出现错误,则及时终止传输。这个方法的实现如下:
“`java
private static int checkAck(InputStream in) throws IOException {
int b = in.read();
if (b == 0) return b;
if (b == -1) return b;
if (b == 1 || b == 2) {
StringBuffer = new StringBuffer();
int c;
do {
c = in.read();
.append((char) c);
} while (c != ‘\n’);
if (b == 1) { // 如果是SCP协议错误,则输出对应的错误信息
System.out.println(.toString());
}
if (b == 2) {
System.out.println(.toString());
}
}
return b;
}
“`
在上面的代码中,我们首先从输入流in中读取一个字节,并判断是否结束或是否正常传输。如果出现错误,则读取反馈信息并输出错误信息,最后返回错误码。
3. 我们将整个文件上传类封装起来,这样以后在需要上传文件时只需要调用这个类即可。具体实现代码如下:
“`java
public class FileUploader {
private static final String DEFAULT_PASSWORD = “”; // 服务器密码
private static final String DEFAULT_USERNAME = “”; // 服务器用户名
private static final int DEFAULT_PORT = 22; // SSH默认端口
/**
* 文件上传
* @param localFilePath 本地文件路径
* @param remoteFilePath 服务器文件路径
* @param serverIP 服务器地址
* @param username 服务器用户名
* @param password 服务器密码
* @param port SSH端口
* @throws chException
* @throws IOException
*/
public static void upload(String localFilePath, String remoteFilePath,
String serverIP, String username, String password, int port)
throws chException, IOException {
ch jsch = new ch();
Session session = jsch.getSession(username, serverIP, port);
session.setPassword(password);
session.connect();
String command = “scp -p -t ” + remoteFilePath;
Channel channel = session.openChannel(“exec”);
((ChannelExec) channel).setCommand(command);
OutputStream out = channel.getOutputStream();
InputStream in = channel.getInputStream();
channel.connect();
if (checkAck(in) != 0) {
System.exit(0);
}
File file = new File(localFilePath);
long filesize = file.length();
command = “C0644 ” + filesize + ” “;
if (localFilePath.lastIndexOf(“/”) > 0) {
command += localFilePath.substring(localFilePath.lastIndexOf(“/”) + 1);
} else {
command += localFilePath;
}
command += “\n”;
out.write(command.getBytes());
out.flush();
if (checkAck(in) != 0) {
System.exit(0);
}
FileInputStream fis = new FileInputStream(localFilePath);
byte[] buf = new byte[1024];
while (true) {
int len = fis.read(buf, 0, buf.length);
if (len
out.write(buf, 0, len);
}
fis.close();
out.flush();
command = “exit\n”;
out.write(command.getBytes());
out.flush();
channel.disconnect();
session.disconnect();
}
/**
* 文件上传
* @param localFile 本地文件
* @param remoteFilePath 服务器文件路径
* @param serverIP 服务器地址
* @param username 服务器用户名
* @param password 服务器密码
* @param port SSH端口
* @throws chException
* @throws IOException
*/
public static void upload(File localFile, String remoteFilePath,
String serverIP, String username, String password, int port)
throws chException, IOException {
upload(localFile.getPath(), remoteFilePath, serverIP, username, password, port);
}
/**
* 文件上传
* @param localFilePath 本地文件路径
* @param remoteFilePath 服务器文件路径
* @param serverIP 服务器地址
* @throws chException
* @throws IOException
*/
public static void upload(String localFilePath, String remoteFilePath, String serverIP)
throws chException, IOException {
upload(localFilePath, remoteFilePath, serverIP, DEFAULT_USERNAME, DEFAULT_PASSWORD, DEFAULT_PORT);
}
/**
* 文件上传
* @param localFile 本地文件
* @param remoteFilePath 服务器文件路径
* @param serverIP 服务器地址
* @throws chException
* @throws IOException
*/
public static void upload(File localFile, String remoteFilePath, String serverIP)
throws chException, IOException {
upload(localFile.getPath(), remoteFilePath, serverIP, DEFAULT_USERNAME, DEFAULT_PASSWORD, DEFAULT_PORT);
}
}
“`
在上述代码中,我们封装了四个不同的文件上传方法。在大多数情况下,使用默认值即可。只有在服务器用户名、密码或SSH端口与默认值不同的情况下,需要使用其中的某个方法。
在本文中,我们介绍了如何使用的功能。在实现过程中,我们使用了Jsch库和SCP协议,通过SSH通道来传输文件。在实际应用中,文件上传是非常常见的需求,使用本文中的代码,可以轻松地实现该功能。如果读者在实现过程中遇到问题,可以参考Jsch库的文档或者留言询问。