java文件操作断点续传

匿名 (未验证) 提交于 2019-12-02 21:52:03

前言:
今天了解了一下断点续传,先记录一下,可能了解的不是特别全面,主要是看网上的实现。
正文:
根据了解其主要实现是两种吧,一种是
断点续传可以通过使用RandomAccessFile(随机访问文件)专门处理文件的类,里面有seek方法和skipBytes()方法可以移动文件指针具体,可以自行了解,另外也可以使用InputStream,里面有一个skip方法可以移动文件指针。实现思路就是每次传输时用缓冲区,每次写入记录当前已经传输的大小,然后保存,暂停时将记录和对应文件永久保存(数据库,文件等)。下次传输时用seek或者skip函数移动指针再读取传输。
关于RandomAccessFile
“r”:以只读的方式打开,调用该对象的任何write(写)方法都会导致IOException异常
“rw”:以读、写方式打开,支持文件的读取或写入。若文件不存在,则创建之。
“rws”:以读、写方式打开,与“rw”不同的是,还要对文件内容的每次更新都同步更新到潜在的存储设备中去。这里的“s”表示synchronous(同步)的意思
“rwd”:以读、写方式打开,与“rw”不同的是,还要对文件内容的每次更新都同步更新到潜在的存储设备中去。使用“rwd”模式仅要求将文件的内容更新到存储设备中,而使用“rws”模式除了更新文件的内容,还要更新文件的元数据(metadata),因此至少要求1次低级别的I/O操作。
关于skip和seek:
调用seek方法类定位大于文件长度的位置将导致IOException,与java.io.InputStream的skip()不同,seek可以定位到文件的任意位置,而skip只能相对于当前位置定位到另一个位置。seek方法是一个相对高开销的操作,需慎重使用,较好使用流数据来构建应用的访问模式。(摘自网络)
下面是两种模拟实现的代码,具体实现可以参考,之后尽量自己写一个javaweb的简单实现
博客1:使用的skip实现
博客2:使用的seek实现

第一种

/**  * 测试实现文件断点续存  * 使用seek函数  * @author ht032  *  */ public class TestFile {  	public static void main(String[] args) { 		// TODO Auto-generated method stub //		File file = new File("d:/1.txt"); //		File file = FileManage.CreateDir("d:/user.txt"); //		FileManage.remove("d:/dir1"); 		try { 			int len = new TestFile().CopyFile("d:/lenet80.png", "d:/temp.png", 67584); 			System.out.print("已经上传:"+len/1024.0); 			System.out.println("KB\n"+len); 			 		} catch (Exception e) { 			// TODO Auto-generated catch block 			e.printStackTrace(); 		} 	}  	private RandomAccessFile sourceFile; 	private RandomAccessFile targetFile;  	/** 	 * 实现复制,需要首先设置source目标文件流 	 *  	 * @param target   目标文件 	 * @param position 源文件的起始位置 	 * @return 返回当前已经传输的文件大小 	 */ 	public int CopyFile(String source, String target, long position) throws Exception { 		if (source == null) 			throw new Exception("source is null!"); 		byte[] buff = new byte[1024]; 		int len = 0;  		try { 			// 打开文件 			targetFile = new RandomAccessFile(target, "rw"); 			sourceFile = new RandomAccessFile(source, "r"); 			 			//文件指针移动到指定位置 			sourceFile.seek(position); 			targetFile.seek(position); 			 			long length = sourceFile.length(); 			System.out.printf("文件总大小%.2fKB\n", length / 1024.0); 			while (true) {  				// int read = rafilein.read(buff); 				int read = sourceFile.read(buff); 				targetFile.write(buff); 				len += read; 				if (len >= length/2 ||read<0) 					break; 			} 		} catch (FileNotFoundException e) { 			// TODO Auto-generated catch block 			e.printStackTrace(); 		} catch (IOException e) { 			// TODO Auto-generated catch block 			e.printStackTrace(); 		} finally { 			// 打开日志文件 //			FileWriter log=new FileWriter(logPath); //			log.write(str); 			try { 				sourceFile.close(); 				targetFile.close();  			} catch (IOException e) { 				// TODO Auto-generated catch block 				e.printStackTrace(); 			} 		} 		return len; 	}  } 

第二种

package FileDemo;  import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.RandomAccessFile;  public class TestFile2 {  	public static void main(String[] args) { 		// TODO Auto-generated method stub 		try { 			int len = new TestFile2().CopyFile("d:/lenet80.png", "d:/temp.png", 11264); 			System.out.print("已经上传:"+len/1024.0); 			System.out.println("KB\n"+len); 			 		} catch (Exception e) { 			// TODO Auto-generated catch block 			e.printStackTrace(); 		} 	}  	private InputStream sourceFile; 	//这里客户端模拟续存也可使用RandomAccessFile //	private RandomAccessFile targetFile; 	private OutputStream targetFile;   	/** 	 * 实现复制,需要首先设置source目标文件流 	 * 使用skip 	 * @param target   目标文件 	 * @param position 源文件的起始位置 	 * @return 返回当前已经传输的文件大小 	 */ 	public int CopyFile(String source, String target, long position) throws Exception { 		if (source == null) 			throw new Exception("source is null!"); 		byte[] buff = new byte[1024]; 		int len = 0;  		try { 			// 打开文件,在后面追加 实现断点续存 			targetFile = new FileOutputStream(target,true); 			sourceFile = new FileInputStream(source); 			 			//文件指针移动到指定位置 			sourceFile.skip(position); 			 //			long length = sourceFile.length(); //			System.out.printf("文件总大小%.2fKB\n", length / 1024.0); 			while (true) {  				// int read = rafilein.read(buff); 				int read = sourceFile.read(buff); 				targetFile.write(buff); 				len += read; 				if( 						read<0 						//leng>4*1024//先传输4KB 						) 					break; 			} 		} catch (FileNotFoundException e) { 			// TODO Auto-generated catch block 			e.printStackTrace(); 		} catch (IOException e) { 			// TODO Auto-generated catch block 			e.printStackTrace(); 		} finally { 			// 打开日志文件 //			FileWriter log=new FileWriter(logPath); //			log.write(str); 			try { 				sourceFile.close(); 				targetFile.close();  			} catch (IOException e) { 				// TODO Auto-generated catch block 				e.printStackTrace(); 			} 		} 		return len; 	}  }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!