多文件并发传输-------文件的表示
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
这样就为多文件并发传输的文件部分做好了铺垫