java文件操作断点续传

21 篇文章 0 订阅

前言:
今天了解了一下断点续传,先记录一下,可能了解的不是特别全面,主要是看网上的实现。
正文:
根据了解其主要实现是两种吧,一种是
断点续传可以通过使用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;
	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值