BIO:实现文件上传下载及封装

步骤:
1.先创建2个Java类:服务端(Server),客户端(Client);
2.创建2个功能工具类:
DataUtil(用于实现发送接收消息以及上传下载文件)
Message(用于对消息的重写)
3.创建两个封装工具类:
ClientUtil(用于对客户端进行封装)
ServerUtil(用于对服务端进行封装)
4.运行的时候先启动服务端,再启动客户端
程序代码:
Client(客户端):

package sc;

import util.ClientUtil;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Client {

    public static void main(String []args){
        Client client = new Client("127.0.0.1",9999);
        Socket socket = client.getSocket();
        System.out.println("客户端启动------");
        try {
            ClientUtil.start(socket);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    Socket socket;
    public Client(String ip,int port) {
        try {
            socket = new Socket(ip,port);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public Socket getSocket() {
        return socket;
    }

}

Server(服务端):

package sc;

import util.ServerUtil;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

    public static void main(String []args){
        Server server = new Server(9999);
        Socket socket = server.acceptSocket();
        System.out.println("服务端启动------");
        try {
            ServerUtil.start(socket);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    ServerSocket serverSocket;
//构造函数
    public Server(int port) {
        try {
            serverSocket = new ServerSocket(port);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public Socket acceptSocket(){
        try {
            Socket socket = serverSocket.accept();
            return socket;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

DataUtil(功能工具类):

package util;

import java.io.*;
import java.net.Socket;

public class DataUtil {
    public static void sendMessage(Socket socket, String msg) {
        try {
            DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
            dos.writeUTF(msg);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String receiveMessage(Socket socket) {
        try {
            DataInputStream dis = new DataInputStream(socket.getInputStream());
            String msg = dis.readUTF();
            return msg;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void sendFile(Socket socket, File file) {
        //1.发送文件名
        DataUtil.sendMessage(socket, file.getName());
        //2.发送文件大小
        DataUtil.sendMessage(socket, file.length() + "");
        //3.发送文件数据
        try (FileInputStream fis = new FileInputStream(file);) {
            transferData(fis, socket.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static File receiveFile(Socket socket) {
        //1.获取文件名
        String fileName = DataUtil.receiveMessage(socket);
        //2.获取文件大小
        int len = Integer.parseInt(DataUtil.receiveMessage(socket));
        //3.获取文件数据
        //fos放在try里面起到一个关流的作用
        try (FileOutputStream fos = new FileOutputStream(fileName);) {
            transferData(socket.getInputStream(), fos, len);

        } catch (IOException e) {
            e.printStackTrace();
        }
        //return一个文件
        return new File(fileName);
    }

    //获取文件数据,用于send方法
    public static void transferData(InputStream is, OutputStream os) {
        int len = 0;
        byte[] arr = new byte[1024];
        try {
            while ((len = is.read(arr)) != -1) {
                os.write(arr, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //获取文件数据,用于receive方法
    public static void transferData(InputStream is, OutputStream os, int len) {
        byte[] arr = new byte[1024];
        try {
        //这里使用长度大于0去判断,主要原因是关流的问题,如果用"(len=is.read(arr))!=-1"去判断,需要 socket.shutdownOutput();
        //不使用长度 >0 判断,就只能传输一次文件,因为len不会读到-1,解决方法要么用多线程,要么用大于0去判断
            while (len > 0) {
                int read = is.read(arr);
                os.write(arr, 0, read);
                len -= read;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}

Message(工具类):

package util;

public class Message {
    private String sendIP;
    private String receiveIP;
    private String Context;

    public Message(String sendIP, String receiveIP, String context) {
        this.sendIP = sendIP;
        this.receiveIP = receiveIP;
        Context = context;
    }

    public void setSendIP(String sendIP) {
        this.sendIP = sendIP;
    }

    public void setReceiveIP(String receiveIP) {
        this.receiveIP = receiveIP;
    }

    public void setContext(String context) {
        Context = context;
    }

    @Override
    public String toString() {
        return "Message{" +
                "sendIP='" + sendIP + '\'' +
                ", receiveIP='" + receiveIP + '\'' +
                ", Context='" + Context + '\'' +
                '}';
    }

}

ClientUtil(工具类,封装客户端):

package util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

public class ClientUtil {
    public static void start(Socket socket) throws Exception{
        System.out.println("请输入选项:");
        System.out.println("0.退出\t1.发送消息\t2.接收消息\t3.发送文件\t4.接收文件");
        Scanner sc = new Scanner(System.in);
        OutputStream os = socket.getOutputStream();
        while(true){
            int n = sc.nextInt();
            os.write(n);
            if(n==0){
                System.out.println("客户端已退出------" );
                break;
            }
            switch (n){
                case 1:
                    String sendIP,receiveIP,context;
                    System.out.println("请输入发送的ip:");
                    sendIP = sc.next();
                    System.out.println("请输入接收的ip:");
                    receiveIP = sc.next();
                    System.out.println("请输入内容:");
                    context = sc.next();
                    Message msg = new Message(sendIP,receiveIP,context);
                    sendMessage(socket,msg);
                    System.out.println("消息发送成功!");
                    break;
                case 2:
                  receiveMessage(socket);
                  System.out.println("消息接收成功!");
                  break;
                case 3:
                    //输入一个文件的地址:如d:\\1.txt
                    System.out.println("请输入发送的文件路径:");
                    String fileName = sc.next();
                    File file = new File(fileName);
                    sendFile(socket,file);
                    System.out.println("文件发送成功!");
                    break;
                case 4:
                    receiveFile(socket);
                    System.out.println("文件接收成功!");
                    break;
                default:
                    System.out.println("请输入合法的选项!");
            }
            System.out.println("请输入选项:");
            System.out.println("0.退出\t1.发送消息\t2.接收消息\t3.发送文件\t4.接收文件");


        }

    }

    public static void sendMessage(Socket socket,Message msg){
        DataUtil.sendMessage(socket,msg.toString());
    }

    public static void receiveMessage(Socket socket){
        String msg = DataUtil.receiveMessage(socket);
        System.out.println(msg);

    }

    public static void sendFile(Socket socket, File file){
        DataUtil.sendFile(socket,file);
    }

    public static void receiveFile(Socket socket){
        File file = DataUtil.receiveFile(socket);
        File path = new File("D:\\ud");
        if(!path.exists())
            path.mkdirs();
        copyFile(file,path+"\\"+file.getName());

    }
    //将文件移动到指定路径,路径为:D:/ud
    public static void copyFile(File file,String path){
        file.renameTo(new File(path));
    }
}

ServerUtil(工具类,封装服务端):

package util;

import java.io.File;
import java.io.InputStream;
import java.net.Socket;

public class ServerUtil {
    public static void start(Socket socket) throws Exception{
        InputStream is = socket.getInputStream();
        while (true){
            int n = is.read();
            System.out.println("您的选择为:"+ n);
            if(n==0){
                System.out.println("服务端已退出------");
                break;
            }
            switch (n){
                case 1:
                    receiveMessage(socket);
                    System.out.println("服务端已接收消息!");
                    break;
                case 2:
                    Message msg = new Message("1","2","3");
                    sendMessage(socket,msg);
                    System.out.println("客户端已接收消息!");
                    break;
                case 3:
                    receiveFile(socket);
                    System.out.println("客户端文件上传成功!");
                    break;
                case 4:
                    File file = new File("d:/1.txt");
                    sendFile(socket,file);
                    System.out.println("客户端已接收到文件!");
                    break;
                default:
                    System.out.println("客户端输入的选项非法,请重新输入!");
            }
        }
    }


    public static void sendMessage(Socket socket,Message msg){
        DataUtil.sendMessage(socket,msg.toString());
    }

    public static void receiveMessage(Socket socket){
        String msg = DataUtil.receiveMessage(socket);
        System.out.println(msg);

    }

    public static void sendFile(Socket socket, File file){
        DataUtil.sendFile(socket,file);
    }

    public static void receiveFile(Socket socket){
        File file = DataUtil.receiveFile(socket);
        File path = new File("D:\\ud");
        if(!path.exists())
            path.mkdirs();
        copyFile(file,path+"\\"+file.getName());

    }
    //将文件移动到指定路径,路径为:D:/ud
    public static void copyFile(File file,String path){
        file.renameTo(new File(path));
    }
}

运行截图
客户端:
在这里插入图片描述
服务端:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值