mfct 关于文件的表示
1:文件片段信息
 SectionInfo
 由于要进行多文件并发传输的功能,并且将文件分片段发送
 我们想到建立一个类 : 片段信息类
 文件片段信息 成员如下:
 int fileHandle;
 //   包含有 文件句柄  唯一标识文件
 long offset;
 //   文件片段的长度
 int size;
 //   文件片段的偏移量
给出构造方法
public  SectionInfo(byte[] sectionInfo) {
//               在进行发送时 是以字节流的形式进行发送的
//               利用字节数组来进行 
          byte[]  bfileHandle=BytesToString.getBytesAt(sectionInfo, 0, 4);
          this.fileHandle=BytesToString.bytesToInt(bfileHandle);
          byte[] boffset  =BytesToString.getBytesAt(sectionInfo, 4, 8);
          this.offset=BytesToString.bytesToLong(boffset);
          byte[] bsize=BytesToString.getBytesAt(sectionInfo,  12, 4);
          this.size=BytesToString.bytesToInt(bsize);
     }
BytesToString 这个类 是一个工具类 具体见另一篇博客字节与其他基本类型的互相转化
2: 文件片段
 FileSection
 文件片段里面 要塞进去文件的内容
 成员 有
SectionInfo sectionInfo;
//片段的基本信息
byte[] values;
//片段的真正内容
由于后面要进行文件的发送 因此想到可以设计
 send 和 receive 函数来接收字节流
 可是 字节流的发送本身与文件的收发 没有太多关联
 可以将其独立出来做一个类 专门用于 字节的收发
 send 和 receive 函数来接收字节流
public void send(DataOutputStream dos, byte[] values) {
          try {
               dos.write(values);
          } catch (IOException e) {
               e.printStackTrace();
          }
     }
 @Override
 public byte[] receive(DataInputStream dis, int size) {
      byte[] data=new byte[size];
      int restSize=size;
      int offset=0;
      int readLen;
      while(restSize>0) {
           readLen= restSize>BUFFER_SIZE ?  BUFFER_SIZE:restSize;
           try {
                dis.read(data, offset, readLen);
                restSize-=readLen;
                offset-=readLen;
           } catch (IOException e) {
                e.printStackTrace();
           }
      }
      
      return data;
      
 }
因此可以将BytesSendReceive 这个类的对象作为文件类的成员
在文件层可以直接调用 send和 receive 进行文件头 以及文件内容的接收 与发送
public void getFileSection(DataInputStream dis){
          byte[] sectionhead=bytesSendReceive.receive(dis,  16);
          sectionInfo=new SectionInfo(sectionhead);
          this.values=bytesSendReceive.receive(dis,  sectionInfo.getSize());
     }
     
 public void sendSection(DataOutputStream dos){
      bytesSendReceive.send(dos, sectionInfo.toBytes());
      bytesSendReceive.send(dos, values);
 }
3.文件片段的组织
最后由于需要检测 文件的收发是否结束 并且将片段组织起来我们设计一个UnreceivedFileSection类
private int fileHandel;
 // 一个文件对应的文件句柄 是相同的
 List sections;
 // 这个文件的片段队列
 构造方法先进行初始化 生成一个大的文件片段
public UnreceivedFileSection1(int  fileHandel, int size) {
          this.fileHandel=fileHandel;
          sections=new ArrayList<SectionInfo>();
          SectionInfo  sectionInfo1=new  SectionInfo(fileHandel, 0L, size);
          sections.add(sectionInfo1);
     }
文件片段不断收发 我们 设计一个方法
public void afterReceiveSection(SectionInfo  section) {
     
          try {
               int index = getRightSection(section);
               SectionInfo org = sections.get(index);
               
               long orgOffset = org.getOffset();
               int orgSize = org.getSize();
               long curOffset = section.getOffset();
               int curSize = section.getSize();
               
               long leftOffset = orgOffset;
               int leftSize = (int) (curOffset - orgOffset);
               long rightOffset = curOffset + curSize;
               int rightSize = (int) (orgOffset + orgSize -  rightOffset);
               
               sections.remove(index);
               if (leftSize > 0) {
                    sections.add(new SectionInfo(fileHandel,  leftOffset, leftSize));
               }
               if (rightSize > 0) {
                    sections.add(new SectionInfo(fileHandel,  rightOffset, rightSize));
               }
          } catch (Exception e) {
               e.printStackTrace();
          }
原始的尚未接收到的片段数据:0:36
 现假设依次接收到:3:7、21:5、16:5、10:6
 (0:36)(3:7) => (0:3, 10:26)
 leftOffset = orgOffset; 0
 leftSize = curOffset - orgOffset; 3
 rightOffset = curOffset + curSize; 10
 rightSize = orgOffset + orgSize - rightOffset; 26
 这样就为多文件并发传输的文件部分做好了铺垫



 京公网安备 11010502036488号
京公网安备 11010502036488号