基于rsync同步算法的文件同步系统JAVA实现(五)—— 重组数据块

作用:

从服务器端发送回来的未匹配数据报中提取数据,并依据匹配的数组和数据报的编号(均是服务器发送回来)与不完整文件进行重新组合,从而生成完整文件。

基本算法:

用一个currentindex变量记录当前数据块编号,

先读取一块返回的数据块,和它的对应编号index(前一个数据块的编号),

如果index>currentindex,根据currentindexfilematchindexs数组(匹配的数组)中读取blockindex(即应该先写入的匹配的数据块),并将currentindex改为index

否则根据index读取blockindex,并将不完整文件的读取指针移动到blockindex*Block

读取一块数据,并写入rebuild文件中,重复(index-currentindex)次,

再将此块返回数据块写入rebuild文件中,

重复以上过程知道返回数据报读取完,

再将剩余的不完整文件写入rebuild文件中。

注意点:

1. 采用随机文件读取,效率可能稍低,但是灵活。

2. 异常处理。

扫描二维码关注公众号,回复: 8529893 查看本文章

3. 比较重要的模块,而且稍有复杂度,待完善。

4. 需要加入后缀处理。

源码:

public void rebuidFile(String filehalf, InputStream inFileBack,
			OutputStream rebuidOut) throws FileNotFoundException, IOException {
		RandomAccessFile randomAccessFile = new RandomAccessFile(filehalf, "r");
		BufferedInputStream backInput = null;
		backInput = new BufferedInputStream(inFileBack);

		byte halfBuffer[] = new byte[ServerCheckSumCreater.BLOCKSIZE];
		byte backBuffer[] = new byte[ServerMatchStarter.DATATOTALSIZE];
		int currentIndex = 0;
		int amount = 0;

		try {

			// getMatchTable
			// DataInputStream dataInputStream = new
			// DataInputStream(inFileBack);
			byte b[] = new byte[4];
			inFileBack.read(b);

			int matchnum = DataConvertUtils.bytes2int(b);
			int matchindexs[] = new int[matchnum];
			for (int i = 0; i < matchnum; i++) {
				inFileBack.read(b);
				matchindexs[i] = DataConvertUtils.bytes2int(b) - 1;
			}
			// dataInputStream.close();
			//
			// boolean rebuildSwitch = false;
			// if (backInput.read(backBuffer) != -1) {
			// byte indexFlag = backBuffer[MatchStarter.INDEXFLAGOFF];
			// switch (indexFlag) {
			// case DatagramType.ALLMATCH: {
			//
			// rebuildSwitch = true;
			// }
			// break;
			// case DatagramType.ZEROMATCH: {
			//
			// // rebuildSwitch = true;
			// }
			// break;
			// }
			// }

			while (backInput.read(backBuffer) != -1) {
				int indexFlag = backBuffer[ServerMatchStarter.INDEXFLAGOFF];
				if (indexFlag == DatagramType.UNMATCHDATA_END)
					break;
				int index = 0;
				int length = backBuffer[ServerMatchStarter.LENGTHOFF];
				byte[] data = new byte[length];
				if (indexFlag == DatagramType.UNMATCHDATA_INDEX_VALID) {
					// index valid
					// seek to currentIndex*TestCreateCheckSum.BLOCKSIZE
					// read index - currentIndex blocks of halffile
					// write to rebuildfile
					// currentIndex = index
					byte[] indexbyte = new byte[4];
					for (int i = 0; i < 4; i++) {
						indexbyte[i] = backBuffer[ServerMatchStarter.INDEXOFF + i];
					}
					index = DataConvertUtils.bytes2int(indexbyte);
					if (index > currentIndex) {
						randomAccessFile.seek(ServerCheckSumCreater.BLOCKSIZE
								* matchindexs[currentIndex]);
						for (int i = 0; i < (index - currentIndex); i++)
							if ((amount = randomAccessFile.read(halfBuffer)) != -1) {
								rebuidOut.write(halfBuffer, 0, amount);
							}
						currentIndex = index;

					}
				}
				// read a block_backfile and write to filerebuild
				for (int i = 0; i < length; i++) {
					data[i] = backBuffer[ServerMatchStarter.DATAOFF + i];// 待优化
				}
				rebuidOut.write(data);
			}

			// write remained halffile data
			for (; currentIndex < matchnum; currentIndex++) {
				int index = matchindexs[currentIndex];
				randomAccessFile.seek(ServerCheckSumCreater.BLOCKSIZE * index);
				if ((amount = randomAccessFile.read(halfBuffer)) != -1) {
					rebuidOut.write(halfBuffer, 0, amount);
				}
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			return;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}


发布了35 篇原创文章 · 获赞 61 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/cql342624757/article/details/10366329