案例:文件上传

案例分析

文件上传案例
1.[客户端]输入流,从硬盘读取文件数据到程序中
2.[客户端]输出流,写出文件数据到服务端
3.[服务端]输入流,读取文件数据到服务端程序
4.[服务端]输出流,写文件数据到服务器硬盘中

实现代码

1.TCPClient客户端

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) throws IOException {
//        1.创建一个本地输入流对象,构造方法中绑定要读取的数据源
        FileInputStream fis = new FileInputStream("G:\\a.txt");
//        2.创建一个客户端对象Socket,构造方法绑定服务器IP地址和端口号
        Socket socket = new Socket("127.0.0.1", 8888);
//        3.使用Socket对象中的方法getOutputStream()获取网络字节输出流OutputStream对象
        OutputStream os = socket.getOutputStream();
//        4.使用本地字节输入流读取本地文件
        int len=0;
        byte[] bytes = new byte[1024];
        while ((len=fis.read(bytes)) !=-1){
//        5.使用网络字节输出流OutputStream对象中的方法write,给服务器发送数据
            os.write(bytes,0,len);
        }
        /*
        解决死循环:上传完文件,给服务器写一个结束标记
            void shutdownOutput()禁止此套接字的输出流
            对于TCP套接字,任何以前写的数据都将被发送,并且后跟TCP的正常连接终止序列,也就是后面加个结束标记
        */
        socket.shutdownOutput();
//        6.使用Socket对象中的方法getInputStream()获取网络字节输入流对象InputStream对象
        InputStream is = socket.getInputStream();
//        7.使用网络字节输入流InputStream对象中的方法read,读取服务器回写的数据
        while ((len=is.read(bytes))!=-1){
            System.out.println(new String(bytes,0,len));
        }
//        8.释放资源(Socket)
        fis.close();
        socket.close();
    }
}

2.TCPServerSocket服务端

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;

/**
 * 服务器端:
 *  读取客户端上传的文件,保存到服务器硬盘,回写数据
 */
public class TCPServerSocket {
    public static void main(String[] args) throws IOException {
        //创建服务器对象:绑定端口号
        ServerSocket server = new ServerSocket(8888);
        /*
        让服务器一只处于监听状态:死循环accept方法
        有一个客户端上传文件,就下载文件
         */

        while (true) {
            //获取请求的客户端对象
            Socket socket = server.accept();
            /*
            使用多线程提高服务器效率,
            只要有一个客户端上传文件,就开启一个线程
             */
            new Thread(new Runnable() {
                //完成文件上传任务
                @Override
                public void run() {
                    try {
                        //使用socket对象中的方法getInputStream
                        InputStream is = socket.getInputStream();
                        //判断文件夹是否存在,不存在就创建
                        File file = new File("G:\\load");
                        if (!file.exists()) {
                            file.mkdirs();
                        }
        /*
        自定义文件的命名规则,防止同名的文件被覆盖
         */
                        String fileName = "p" + System.currentTimeMillis() + new Random().nextInt(99999) + ".txt";
                        //创建本地输出流对象
                        FileOutputStream fos = new FileOutputStream(file + "\\" + fileName);
                        //边读网络数据边写进文件
                        int len = 0;
                        byte[] bytes = new byte[1024];
                        while ((len = is.read(bytes)) != -1) {
                            fos.write(bytes);
                        }
                        //使用socket对象中的方法getOutputStream回写数据
                        OutputStream os = socket.getOutputStream();
                        os.write("上传成功".getBytes());
                        //释放资源
                        fos.close();
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();

        }
//        server.close();//服务器不用关闭
    }
}
posted @ 2021-03-31 23:00  一名初学者  阅读(86)  评论(0)    收藏  举报