Java作业11--断点续传半成品

一、利用socket实现文件传输断点续传

实现方法

采用的方法是在客户端传输失败之后服务器保持当前存储的位置信息,在下一次客户端发送这个数据时,读取位置信息,发送给客户端让客户端从断点处发送数据

改善

这段代码有很多bug,也有很多需要完善的地方用户体验不好,以后在加以修改,例如:应当以命令的方式请求服务器,验证有验证的命令,发送数据有发送数据的命令,发送文件基本信息的命令

服务器端

public class server {

    public static void main(String[] args) throws IOException{

        int sum=0;//记录读取位置断点续传
        String fileName=null;
        //BufferedWriter writer=null;
        RandomAccessFile rdf=null;
        ServerSocket serverSocket=new ServerSocket(8888);
        Socket socket=serverSocket.accept();//监听

        //读取数据
        BufferedReader dataIn=new BufferedReader(new InputStreamReader(socket.getInputStream()));
        BufferedWriter dataout=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        String data=null;
        StringBuffer strBuf=new StringBuffer();
        while((data=dataIn.readLine())!=null){
            if(data.contains("Eof")) {//读到Eof结束
                break;
            }

            strBuf.append(data);//添加到bufferedReader数组中
        }

        fileName=strBuf.toString();//第一次发送的是文件名

        System.out.println("开始接收数据");

        //
        //开始接收数据
        //
        rdf=new RandomAccessFile(new File(fileName), "rw");
        char[] cbuf=new char[512];//传输文件数据一次传输512B
        int len;

        //发送验证信息断点续传,先保存位置再发送给客户端
        dataout.write(len=rdf.readInt());
        dataout.write("Eof"+"\n");
        dataout.flush();

        rdf.seek(len);//进行移动

        try{    

            while((len=dataIn.read(cbuf, 0, 512))!=-1){
                rdf.writeBytes(new String(cbuf,0,len));
                sum=sum+len;
            }
            System.out.println("数据传输完成");

        }catch(Exception ex){

            System.out.println("数据传输错误");
        }

        rdf.seek(0);
        rdf.writeLong(sum);//在头部添加位置信息,其实应该在和他名字相同的文件中添加信息

        //关闭
        rdf.close();
        dataIn.close();
        dataout.close();
        socket.close();

    }
}

功能模块没有分开,应该以命令方式执行,在保存位置的时候不应该在源文件中保存数据应该重新创建一个状态文件,将文件的信息、但前读取大小等信息一一写入进去

客户端

package socket;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.RandomAccessFile;
import java.net.Socket;
import java.net.UnknownHostException;

public class client {

    public static void main(String[] args) throws UnknownHostException, IOException {
        // TODO Auto-generated method stub
        boolean flag=false;

        String path="e:\\test.txt";
        //String path="E:\\安装包\\jdk-8u101-windows-x64.exe";

        RandomAccessFile reader=new RandomAccessFile(new File(path), "r");
        Socket socket=new Socket("127.0.0.1",8888); //连接数据库

        //
        //传输文件基本信息
        //
        BufferedWriter netWriter=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        netWriter.write(path.substring(path.lastIndexOf("\\")+1,path.length())+"\n");
        netWriter.write("Eof"+"\n");
        //写文件完成Eof结束    
        netWriter.flush();

        //
        //读取服务器发送数据
        //
        BufferedReader dataIn=new BufferedReader(new InputStreamReader(socket.getInputStream()));
        int dataint=0;
        String data=null;
        StringBuffer strBuf=new StringBuffer();

        dataint=dataIn.read();
        flag=true;

        reader.seek(dataint);//设置断点处坐标

        //
        //发送文件数据
        //
        if(flag){
            netWriter=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));//传输数据
            byte[] cbuf=new byte[512];//传输文件数据一次传输512B

            String len;

            while((len=reader.readLine())!=null){
                netWriter.write(len);
                netWriter.flush();

            }
            reader.close();
        }

        System.out.println("传输完成");

        netWriter.close();
        dataIn.close();
        socket.close();
    }

}

同服务器端一样太乱了,慢慢加以修改

二、序列化、反序列化和网络序列化

public class main {

    public static void main(String[] args) throws ClassNotFoundException, IOException, InterruptedException {
        // TODO Auto-generated method stub
        objectSer();
        objectAnSer();
        NetAnSer();
    }

    //
    //序列化函数
    //
    public static void objectSer(){
        ObjectOutputStream out;
        try {
            out = new ObjectOutputStream(new FileOutputStream("test.txt"));//序列化
            out.writeObject(new Mytest("tang", "man", "201430185022"));
            out.writeObject(new Mytest("tang1", "man", "20143018"));
            out.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    //
    //反序列化函数
    //
    public static void objectAnSer(){


        ObjectInputStream in;
        Mytest myTest=null;
        try {
            in = new ObjectInputStream(new FileInputStream("test.txt"));//反序列化
            myTest = (Mytest)in.readObject();
            in.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }   
        catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.println(myTest.name);
        System.out.println(myTest.sex);

    }

    //
    //网络反序列化函数
    //
    public static void NetAnSer() throws IOException, ClassNotFoundException, InterruptedException{
        ServerSocket serverSocket=new ServerSocket(9999);

        Socket socket=serverSocket.accept();//开始监听

        System.out.println("good");
        //接收客户端发来的序列化数据
        ObjectInputStream objectReader=new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
        //读取数据
        Object ob=objectReader.readObject();
        Mytest mytest=null;
        if(ob==null)
            System.out.println("error");
        else 
            mytest=(Mytest)ob;
        System.out.println(mytest.id);
        objectReader.close();
    }
}

客户端

public static void main(String[] args) throws IOException {

        Socket socket=new Socket("127.0.0.1", 9999);

        ObjectOutputStream writer=new ObjectOutputStream(socket.getOutputStream());

        Mytest myTest=new Mytest("tangbo", "tangbo","tangbo");
        writer.writeObject(myTest);
        writer.flush();
        writer.close();
    }

}

数据结构

public class Mytest implements Serializable
{
    transient String name;//序列化时阻止该变量被序列化到文件中
    String sex;
    String id;
    public Mytest(String name,String sex,String id) {
        // TODO Auto-generated constructor stub
        this.name=name;
        this.sex=sex;
        this.id=id;
    }
}

三、总结

经过这次作业我了解到断点续传,并按照思路写出具体的代码,但还有很多需要改进的地方,这还不能算是一个网络传输文件的程序,有太多需要修改的地方,这次作业我学到了很多东西

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
el-upload组件是Element UI中的一个文件上传组件,它支持断点续传功能。断点续传是指在文件上传过程中,如果上传中断或失败,可以从中断的位置继续上传,而不需要重新上传整个文件。 要实现el-upload的断点续传功能,可以按照以下步骤进行操作: 1. 在el-upload组件中设置`:auto-upload="false"`,这样文件不会自动上传。 2. 监听el-upload组件的`change`事件,获取选择的文件。 3. 将文件分成多个块(chunk),每个块的大小可以根据需求进行设置。 4. 使用XMLHttpRequest或者axios等工具发送每个块的数据到服务器,并在请求头中设置`Content-Range`来指定块的范围。 5. 服务器接收到每个块的数据后,将其保存到指定位置。 6. 当所有块都上传完成后,服务器将这些块合并成完整的文件。 以下是一个示例代码,演示了如何使用el-upload实现断点续传功能: ```html <template> <el-upload class="upload-demo" :action="uploadUrl" :auto-upload="false" :on-change="handleChange" :on-remove="handleRemove" :file-list="fileList" > <el-button slot="trigger" size="small" type="primary">选取文件</el-button> <el-button style="margin-left: 10px;" size="small" type="success" @click="handleUpload">上传文件</el-button> </el-upload> </template> <script> export default { data() { return { uploadUrl: '/upload', // 上传接口地址 fileList: [], // 文件列表 }; }, methods: { handleChange(file) { this.fileList = file.raw; }, handleRemove(file) { // 移除文件时的操作 }, handleUpload() { // 上传文件时的操作 // 将文件分块并上传 // 合并块文件 }, }, }; </script> ``` 请注意,上述代码中的`uploadUrl`需要根据实际情况进行设置,用于指定文件上传的接口地址。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值