• 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方法里写道:

java开发中serviceimpl_客户端


程序死循环原理:

在客户端里,文件上传使用fis.read(bytes)方法来读取本地文件,在while里,无法将fis.read(bytes)读到-1,也就是无法读到结束标记,无法将结束标记传给服务器。

在服务器里,服务器通过is.read(bytes)来获取客户端所上传的文件,由于无法获取到客户端所发来的结束标记,就会产生阻塞状态,从而无法将程序继续执行下去而产生死循环。

在客户端,由于无法读到服务器所回写的数据,客户端也进入了阻塞状态,从而客户端也进行死循环。

解决方案:

在客户端里,在将文件上传给服务器后,写一个结束的标记传给服务器

然后用到一个方法:

java-net-Socket里的

void shutdownOutput()

方法功能:
禁用此套接字的输出流
意思就是给流一个结束的标记

5.结束语:

如果有看到的铁汁,也请点个赞再走,球球了,蟹蟹了。