1. 程式人生 > >RandomAccessFile 檔案分割、合併

RandomAccessFile 檔案分割、合併

package com.io;


import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;


/**
 * 檔案分割、合併
 * @author Administrator
 *
 */
public class MyRandomAccessFile {

private int size = 1024*1024*10 * 4;//要分割的大小40M
private long frist = 0;//上一次分割的節點位置

public int getSize() {
return size;
}


public void setSize(int size) {
this.size = size;
}


public long getFrist() {
return frist;
}


public void setFrist(long frist) {
this.frist = frist;
}


MyRandomAccessFile(){

}

MyRandomAccessFile(int size){
this.size = size;
}

/**
* 檔案分割
* @param inputFile要分割的檔案
* @param outFile要輸出的檔案目錄
* @throws IOException
*/
public void segmentation(File inputFile,File outFileDirectory) throws IOException{
if(inputFile != null && !inputFile.exists()){
return;
}
if(inputFile.isDirectory()){
       return;
   }
try(
/**
* JDK 建構函式
* RandomAccessFile(File file, String mode) 建立一個隨機訪問檔案流讀,隨意寫來,由 File引數指定的檔案。 
* mode引數指定的檔案被開啟的訪問模式。允許的值和它們的意思是:
"r" Open for reading only. Invoking any of the write methods of the resulting object will cause an IOException to be thrown.  
"rw" Open for reading and writing. If the file does not already exist then an attempt will be made to create it.  
"rws" Open for reading and writing, as with "rw", and also require that every update to the file's content or metadata be written synchronously to the underlying storage device.  
"rwd"   Open for reading and writing, as with "rw", and also require that every update to the file's content be written synchronously to the underlying storage device.  
*/
RandomAccessFile radaf = new RandomAccessFile(inputFile, "r");
BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outFileDirectory));
){
radaf.seek(frist);
byte[] b = new byte[size];
int last;
while((last = radaf.read(b)) != -1){
outputStream.write(b, 0, last);
outputStream.flush();
frist += last;
break;
}
}
}


/**
* 根據要分割檔案的大小除於分割大小,得到要分割成幾份,
* 並得到分割幾份後的檔名稱
* @param inputFile要分割檔案
* @param size 分割大小
* @param fileInitName分割幾份後要叫的檔名稱
* @return 分割幾份後的檔名稱
*/
public List<String> getFileName(File inputFile,long size,String fileInitName){
long length = inputFile.length();
double ceil = Math.ceil(length*1.0/size);
//修正大小
        if(size > length){
        size = length;
        }
List<String> name = new ArrayList<>((int)ceil);
for (int i = 0; i < (int)ceil; i++) {
//這裡加上盤,只是為了方便
name.add("G:/" + i + fileInitName);
}
return name;
}


/**
* 合併檔案
* @param listName要合併的檔名
* @param file 輸出的檔案地址
* @throws IOException
*/
    public void mergeFile(List<String> listName,File file) throws IOException{
        
    Vector<InputStream> v = new Vector<>();
    for (String string : listName) {
v.add(new BufferedInputStream(new FileInputStream(new File(string))));
}
    try(
    // true = 檔案輸出的追加
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file,true));
    //棧
    SequenceInputStream sequence = new SequenceInputStream(v.elements());
    ){
    byte[] b = new byte[size];
    int len = 0;
    while((len = sequence.read(b))!= -1){
    bos.write(b, 0, len);
    bos.flush();
    }
    }
    }

public static void main(String[] args){
MyRandomAccessFile my = new MyRandomAccessFile();
//分割檔案
File inputFile = new File("G:/123456789.mp4");
//文字分割過後,可直接開啟,但視訊、音訊、壓縮檔案等,分割後,不能直接開啟。
//= new File("G:/123456789.txt");
//分割後的檔名
List<String> fileName = my.getFileName(inputFile, my.getSize(), "zsf.mp4");
//檔案分割,並輸出
for (String string : fileName) {
try {
my.segmentation(inputFile, new File(string));
} catch (IOException e) {
e.printStackTrace();
}
}
//檔案合併
try {
my.mergeFile(fileName, new File("G:/98aa.mp4"));
} catch (IOException e) {
e.printStackTrace();
}
}
}