zoukankan      html  css  js  c++  java
  • Java IO 流 -- 随机读取和写入流 RandomAccessFile (文件分割和合并)

    RandomAccessFile 相对其它流多了一个seek() 方法指定指针的偏移量。

    1、指定起始位置读取剩余内容

    public static void test01() throws IOException {
    		RandomAccessFile raf = new RandomAccessFile("src/com/xzlf/io/CopyFile.java", "r");
    		// 随机读取
    		raf.seek(2);
    		byte[] flush = new byte[1024];
    		int len = -1;
    		while((len=raf.read(flush)) != -1) {
    			System.out.println(new String(flush,0,len));
    		}
    		raf.close();
    	}
    

    2、指定起始位置和实际大小

    public static void test02() throws IOException {
    		RandomAccessFile raf = new RandomAccessFile("src/com/xzlf/io/CopyFile.java", "r");
    		// 起始位置
    		int beginPos = 2+1026;
    		// 实际大小
    		int actualSize = 1026;
    		// 随机操作
    		raf.seek(beginPos);
    		// 缓冲容器
    		byte[] flush = new byte[1024];
    		int len = -1;
    		while ((len = raf.read(flush)) != -1) {
    			if(actualSize > len) {
    				System.out.println(new String(flush, 0, len));
    				actualSize -= len;
    			}else {
    				System.out.println(new String(flush, 0, actualSize));
    				break;
    			}
    		}
    		raf.close();
    	}
    

    3、封装

    package com.xzlf.io;
    
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    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.OutputStreamWriter;
    import java.io.RandomAccessFile;
    import java.io.SequenceInputStream;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Vector;
    
    public class SplitFile {
    	// 源头
    	private File src;
    	// 目的地
    	private String destDir;
    	// 所有分割后文件存储路劲
    	List<String> destPath;
    	// 每块大小
    	int blockSize;
    	// 块数
    	int size;
    	public SplitFile(String srcPaht, String destDir) {
    		this(srcPaht, destDir, 1024);
    	}
    	
    	public SplitFile(String srcPath, String destDir, int blockSize) {
    		this.src = new File(srcPath);
    		this.destDir = destDir;
    		this.blockSize = blockSize;
    		this.destPath = new ArrayList<String>();
    		
    		init();
    	}
    	
    	// 初始化
    	private void init() {
    		// 总长度
    		long len = this.src.length();
    		// 块数
    		this.size = (int) Math.ceil(len * 1.0 / blockSize);
    		for(int i = 0; i < size; i++) {
    			this.destPath.add(this.destDir + "/" + i + "-" + this.src.getName());
    		}	
    	}
    	
    	/**
    	 * 分割
    	 * 1、计算每一块的起始位置及大小
    	 * 2、分割
    	 * @throws IOException
    	 */
    	public void split() throws IOException {
    		File src = this.src;
    		// 总长度
    		long len = src.length();
    		// 起始位置和实际大小
    		int beginPos = 0;
    		int actualSize = 0;
    		for(int i = 0; i < size; i++) {
    			beginPos = i * blockSize;
    			if(i == size -1) { // 最后一块
    				actualSize = (int) len;
    			}else {
    				actualSize = blockSize;
    				len -= actualSize; // 剩余量
    			}
    			System.out.println(i + "-->" + beginPos);
    			splitDetail(i, beginPos, actualSize);
    		}
    	}
    	
    	/**
    	 * 指定第 i 块、起始位置、实际长度
    	 * @param i
    	 * @param beginPos
    	 * @param actualSize
    	 * @throws IOException
    	 */
    	private void splitDetail(int i, int beginPos, int actualSize) throws IOException {
    		RandomAccessFile raf = new RandomAccessFile(src, "r");
    		RandomAccessFile raf2 = new RandomAccessFile(destPath.get(i), "rw");
    		raf.seek(beginPos);
    		byte[] flush = new byte[1024];
    		int len = -1;
    		while((len = raf.read(flush)) != -1) {
    			if(actualSize > len) {// 获取本次读取的所有内容
    				raf2.write(flush, 0, len);
    				actualSize -= len;
    			}else {
    				raf2.write(flush, 0, actualSize);
    				break;
    			}
    		}
    		raf.close();
    		raf2.close();
    	}
    	
    	/**
    	 * 文件的合并
    	 * @param destPaht
    	 * @throws IOException 
    	 */
    	public void merge(String destPath) throws IOException {
    		// 输出流
    		OutputStream os = new BufferedOutputStream(new FileOutputStream(destPath, true));
    		Vector<InputStream> vi = new Vector<InputStream>();
    		
    		// 输入流
    		for (int i = 0; i < this.destPath.size(); i++) {
    			vi.add(new BufferedInputStream(new FileInputStream(this.destPath.get(i))));
    		}
    		SequenceInputStream sis = new SequenceInputStream(vi.elements());
    		// 文件拷贝
    		byte[] flush = new byte[1024];
    		int len = -1;
    		while((len = sis.read(flush)) != -1) {
    			os.write(flush, 0, len);
    		}
    		
    		// 释放资源
    		os.flush();
    		os.close();
    		sis.close();
    	}
    }
    
    

    4、添加测试代码测试:

    	public static void main(String[] args) throws IOException {
    //		SplitFile sf = new SplitFile("src/com/xzlf/io/CopyFile.java", "dest");
    		SplitFile sf = new SplitFile("水电费.png", "dest");
    		sf.split();
    //		sf.merge("CopyFile.java");
    		sf.merge("水电费-merge.png");
    	}
    
    重视基础,才能走的更远。
  • 相关阅读:
    Mybatis入门环境搭建
    sts,eclipse里面配置tomcat
    IDEA-导入本地所需要的jar包
    Java使用poi生成Excel,生成两种表格下拉框
    Java使用poi生成Excel表格
    Java synchronized(this)锁住的是什么
    Java多线程之使用ATM与柜台对同一账户取钱
    Java多线程对同一个对象进行操作
    Java Socket通信实例
    java基本数据类型和引用数据类型的区别
  • 原文地址:https://www.cnblogs.com/xzlf/p/12681532.html
Copyright © 2011-2022 走看看