- Java网络文件上传
- 前言
- 步骤
- 代码
- 常见问题解决
- 结束语
1.前言:
本次小程序实现的是,通过网络字节流与本地字节流来实现在客户端将文件上传到服务器端。
2.步骤:
客户端:
1.通过本地字节输入流将文件读取到内存
2.将内存中的数据通过网络输出流传给服务器端
3.将在服务器端传来的数据通过网络字节输入读取到本地
4.打印在服务器传来的数据到控制台
5.释放掉资源服务器端:
1.通过网络输入流将客户端传来的数据接收
2.用本地字节输出流将接收的数据写入到指定的文件里
3.写入之前先判断文件是否存在,不存在先创建文件
4.接收到数据并保存到本地后,将返回客户端一句话
5.释放掉资源
3.代码演示:
客户端:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class TcpClient {
public static void main(String[] args) {
try {
// “127.0.0.1”代表为本机,并使用8888端口
Socket socket = new Socket("127.0.0.1",8888);
OutputStream os = socket.getOutputStream();
FileInputStream fis = new FileInputStream("E:\\JavaFileTest\\TCP\\Client\\1.jpg");
int len = 0;
byte[] bytes = new byte[1024];
while ((len = fis.read(bytes)) != -1) {
os.write(bytes,0,len);
}
// 由于fis.read(bytes)不会读取到结束标记,也不会将结束标记写给服务器,从而会产生死循环不会将程序向下执行
// 所以使用Socket里的方法shutdownOutput()方法来写给服务器应该结束标记
socket.shutdownOutput();
InputStream is = socket.getInputStream();
while ((len = is.read(bytes)) != -1) {
System.out.println(new String(bytes,0,len));
}
fis.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务器端:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer {
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(8888);
Socket socket = server.accept();
InputStream is = socket.getInputStream();
File file = new File("E:\\JavaFileTest\\TCP\\Server");
if (file.exists()) {
file.mkdirs();
}
FileOutputStream fos = new FileOutputStream(file + "\\1.jpg");
int len = 0;
byte[] bytes = new byte[1024];
while ((len = is.read(bytes)) != -1) {
// is.read()读取不到客户端所上传文件的结束标记,read方法就会进入阻塞的状态,使用进行死循环而不会将程序继续执行下去
fos.write(bytes,0,len);
}
OutputStream os = socket.getOutputStream();
os.write("上传成功 for server".getBytes());
fos.close();
socket.close();
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
4.所带问题解决:
网络文件的上传案例,初次写的时候,如果没有考虑read方法的阻塞问题,就会在程序执行后,虽然文件可以上传到服务器本地,但是会出现程序结束不掉的问题。
在Java的API里,java-io-FileInputStream里的read方法里写道:
程序死循环原理:
在客户端里,文件上传使用fis.read(bytes)方法来读取本地文件,在while里,无法将fis.read(bytes)读到-1,也就是无法读到结束标记,无法将结束标记传给服务器。
在服务器里,服务器通过is.read(bytes)来获取客户端所上传的文件,由于无法获取到客户端所发来的结束标记,就会产生阻塞状态,从而无法将程序继续执行下去而产生死循环。
在客户端,由于无法读到服务器所回写的数据,客户端也进入了阻塞状态,从而客户端也进行死循环。
解决方案:
在客户端里,在将文件上传给服务器后,写一个结束的标记传给服务器
然后用到一个方法:
java-net-Socket里的
void shutdownOutput()
方法功能:
禁用此套接字的输出流
意思就是给流一个结束的标记
5.结束语:
如果有看到的铁汁,也请点个赞再走,球球了,蟹蟹了。