【Java项目】多文件传输:文件未接收片段池

该篇设计主要针对文件传输异常,确保可恢复传送的机制。该机制,可以说是接收方每接收一块文件片段,需要重计算文件未接收片段。确保文件传输完整性。

一、如何计算未接收片段

在这里插入图片描述

二、实现类

该类主要针对接收端,根据文件长度,定义未接收片段,每一段,重计算未接收片段。若传输失败,则可以获取未接收片段。

package man.kuke.core;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

/**
 * <p>文件片段池<p/>
 *
 *
 * 断点续传:在接收过程中,若出现接收异常,希望能在下一次接收过程中,
 * 接着上一次接收内容的基础上继续接收;即,接收过的内容不必再次传输。
 * 对于文件级别的断点续传,相对简单,在更高层面,检查接收到的文件,和未接收的文件,再进行一
 * 未接收文件的传输操作即可
 *
 * 对于大文件。再接收过程,如果已经接收了一部分,那么,需要知道哪些部分接收失败
 * 下一次传输过程,只传输这个文件的部分内容
 *
 * 每接收一块文件片段,都可得到这个文件片段的offset和len
 * 只要处理片段的数据,就可以得到未接收的文件片段数据
 *
 *
 */
public class UnreceiveSection {
    /**
     * 文件ID
     */
    private long fileId;
    /**
     * 未接收片段
     */
    private List<SectionHander> sectionHanderList;


    public UnreceiveSection(long fileId,long fileLenth) {
        this.fileId = fileId;
        this.sectionHanderList = new LinkedList<>();
        sectionHanderList.add(new SectionHander(fileId,0,fileLenth));
    }

    public UnreceiveSection(int fileId) {
        this.fileId = fileId;
    }


    //TODO Test

    /**
     * 填充未接收片段列表
     * 1、首先锁定填充区间
     * 2、重新计算未填充片段,产生左片段,右片段
     * @param sectionHander
     * @return 片段接收是否完毕
     */
    public boolean receiveSection(SectionHander sectionHander) {
        for (int index = 0; index < sectionHanderList.size(); index++) {
            SectionHander curSection = sectionHanderList.get(index);
            long curStart = curSection.getOffset();
            int curEnd = (int) (curStart + curSection.getLen() - 1);
            long receiveStart = sectionHander.getOffset();
            int receiveEnd = (int) (receiveStart + sectionHander.getLen() - 1);
            if (curStart <= receiveStart && receiveEnd <= curEnd) {
                //删除满足未接收片段,重新加入新片段
                this.sectionHanderList.remove(curSection);
                //当前区间右边界大于sectionHander的右边界
                if (curEnd - receiveEnd > 0) {
                    //加入左片段
                    this.sectionHanderList.add(index,new SectionHander(fileId,receiveEnd + 1, (int) (curEnd - receiveEnd )));
                }
                //当前区间左边界小于sectionHander的右边界
                if (receiveStart -curStart  > 0) {
                    //加入右片段
                    this.sectionHanderList.add(index,new SectionHander(fileId,curStart, (int) (receiveStart -curStart )));
                }
                return isAllReceived();
            }
        }

        System.out.println("分片[" + sectionHander + "] 不存在");
        return true;
    }


    public List<SectionHander> getSectionHanderList() {
        return sectionHanderList;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        UnreceiveSection that = (UnreceiveSection) o;
        return fileId == that.fileId;
    }

    @Override
    public int hashCode() {
        return Objects.hash(fileId);
    }

    public boolean isAllReceived() {
        return sectionHanderList.isEmpty();
    }

    public Iterator<SectionHander> getIterator() {
        return new Iter();
    }


    // 遍历未接收片段
    private class Iter implements Iterator<SectionHander>{
        private int index = 0;
        @Override
        public boolean hasNext() {
            boolean next = index < sectionHanderList.size();
            if (next) {
                index = 0;
            }
            return next;
        }

        @Override
        public SectionHander next() {
            return sectionHanderList.get(index++);
        }

        @Override
        public void remove() {
        }
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值