天天看點

RandomAccessFile在本地實作僞斷點續傳

準備:在磁盤中 準備一個目錄檔案

實作:将該檔案複制到目标路徑中,關掉程式,再重新打開可以在原位置繼續複制。

需求如下:

  1. 過程中顯示檔案的拷貝的百分比
  2. 複制過程中關掉程式。
  3. 重新啟動該程式時,若上次沒有拷貝完,則提示上次拷貝還沒完成,是否從上次的位置開始拷貝! 1. 是:從上次結束的位置繼續拷貝。0 否:從頭開始拷貝

代碼如下:

public class Test02 {
	
	public static void main(String[] args) {
		
		File srcFile = new File("D:/test/test.zip");
		File dstFile = new File("D:/test/test2.zip");
		File logFile = new File(dstFile.getParentFile(),dstFile.getName() + ".log.raf");
		RandomAccessFile logRaf = null;
		long start = 0L;
		try {
			if(logFile.exists() && logFile.length() > 0){
				
				Scanner sc = new Scanner(System.in);
				System.out.println("上次拷貝結束:1 繼續拷貝 0重新拷貝");
				switch (sc.nextInt()) {
				case 1:
					logRaf = new RandomAccessFile(logFile, "rw");
					start = logRaf.readLong();
					copy(srcFile,dstFile,start);
					break;
				case 0:
					copy(srcFile,dstFile,start);
				default:
					System.out.println("輸入錯誤,請輸入一個 0或1 的數字 進行選擇");
					break;
				}
				
			}else{
				copy(srcFile,dstFile,start);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	
		
		
	}
	
	
	
	
	public static void copy(File srcDir,File dstFile,long start){
		
		long length = srcDir.length();
		File logRaf = new File(dstFile.getParentFile(),dstFile.getName() + ".log.raf");
		RandomAccessFile srcRandom = null;
		RandomAccessFile dstRandom = null;
		RandomAccessFile logRandom = null;
		try {
			
			if(length == 0){
				return;
			}
			
			srcRandom = new RandomAccessFile(srcDir, "rw");
			dstRandom = new RandomAccessFile(dstFile, "rw");
			logRandom = new RandomAccessFile(logRaf, "rw");
			
			long sum = start;
			int read = -1;
			int startavg = 0;
			byte b[] = new byte[1024];
			srcRandom.seek(start);
			while((read = srcRandom.read(b)) != -1){
				dstRandom.write(b,0,read);
				sum += read;
				
				int avg = (int)(100 * sum/length);
				if(avg > startavg){
					System.out.println("已經完成了%:" + avg);
					startavg = avg;
				}
				logRandom.seek(0);
				logRandom.writeLong(sum);
				Thread.currentThread().sleep(1);//降低寫的速度 效果明顯
			}
			
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			
			if(logRandom != null){
				try {
					logRandom.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			
			if(dstRandom != null){
				try {
					dstRandom.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			
			if(srcRandom != null){
				try {
					srcRandom.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			logRaf.delete();
		}
		
		
		
	}