PrintStream 和 PrintWrite 打印流:
|-- 提供打印方法,可以打印各種各種數據值,並保持了數據的表現形式。不保證數據大小。
SequenceInputStream 序列流:
|-- 將多個流合併成一個流,按順序輸出。
|-- 接收一個Enumeration。可以用容器封裝讀取流,然後把容器轉換成Enumeration對象。
RandomAccessFile:。。。多線程。。。斷點。。。
package myio;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Properties;
import myfilter.FilterByName;
/*
* 文件切割器
*
* 把一個文件按照指定大小切成多個文件。
* 1.一個讀取流,多個輸出流。文件類型不確定,使用字節流。操作文件使用File...
*
* 把切割後的文件碎片合併成一個文件。
*
* */
public class CutFile {
// 要切割的文件
private File cutFile;
// 輸出文件的前綴
private int prefix = 1;
// 輸出文件的後綴
private String suffix = ".part";
// 輸出文件的大小
private int size = 1024 * 1024;
public CutFile(File cutFile) {
this.cutFile = cutFile;
}
public static void main(String[] args) throws IOException {
CutFile cf = new CutFile(new File("141.mp3"));
cf.cutFile(cf.cutFile, cf.size);
cf.mergeFile(cf.getOutDir());
}
/*
* 獲取文件碎片所在目錄,遍歷文件碎片 讀取切割信息 創建序列流 合併文件
*/
private void mergeFile(File dir) throws IOException {
if (!dir.exists())
throw new RuntimeException("找不到指定目錄");
// 過濾目錄,得到配置文件
File proFile = checkProFile(dir, ".properties");
// 讀取配置文件信息到集合中
Properties pro = new Properties();
pro.load(new FileReader(proFile));
// 獲取配置信息
String suffix = pro.getProperty("suffix");
int CutNum = Integer.parseInt(pro.getProperty("CutNum"));
String fileName = pro.getProperty("cutFile");
// 過濾目錄,得到碎片文件
File[] partFiles = checkPartFiles(dir, suffix, CutNum);
// 創建一個集合存儲讀取流。
ArrayList<FileInputStream> list = new ArrayList<FileInputStream>();
for (File file : partFiles) {
// 添加讀取流到集合中
list.add(new FileInputStream(file));
}
//將碎片合併到指定文件中
write2file(list, fileName);
}
private void write2file(ArrayList<FileInputStream> list, String fileName) throws IOException {
Enumeration<FileInputStream> en = Collections.enumeration(list);
// 創建一個合併流
SequenceInputStream sis = new SequenceInputStream(en);
byte[] b = new byte[size];
int len = 0;
// 創建一個輸出流,合併文件
FileOutputStream fos = new FileOutputStream(new File(getOutDir(),fileName));
while ((len = sis.read(b)) != -1) {
fos.write(b, 0, len);
}
fos.close();
sis.close();
}
private File[] checkPartFiles(File dir, String suffix, int CutNum) {
File[] partFiles = dir.listFiles(new FilterByName(suffix));
if (partFiles.length != CutNum)
throw new RuntimeException("碎片文件異常");
return partFiles;
}
private File checkProFile(File dir, String string) {
File[] proFile = dir.listFiles(new FilterByName(string));
if (proFile.length != 1)
throw new RuntimeException("配置文件異常");
return proFile[0];
}
/////////////////////////////////////////////////////////////////////////////////
private void cutFile(File file, int size) throws IOException {
// 創建一個讀取源文件的讀取流
FileInputStream fis = new FileInputStream(file);
// 自定義切割大小
byte[] buf = new byte[size];
int len = 0;
// 循環輸出,每次使用不同的輸出流。
while ((len = fis.read(buf)) != -1) {
FileOutputStream fos = new FileOutputStream(getOutFile());
fos.write(buf, 0, len);
fos.close();
}
fis.close();
// 寫入切割信息到配置文件
write2conf();
}
private void write2conf() throws IOException {
int CutNum = getFileCutNum(size);
Properties pro = new Properties();
pro.setProperty("suffix", suffix);
pro.setProperty("cutFile", cutFile.getName());
pro.setProperty("CutNum", CutNum + "");
FileWriter fw = new FileWriter(new File(getOutDir(), getFileName() + ".properties"));
pro.store(fw, "cutconf");
}
private int getFileCutNum(int size) {
return (int) Math.ceil(getFileLength() / (double) size);
}
private long getFileLength() {
return cutFile.length();
}
private String getFileName() {
return cutFile.getName();
}
private File getOutFile() throws IOException {
File outFile = new File(getOutDir(), (prefix++) + suffix);
return outFile;
}
private File getOutDir() throws IOException {
File outDir = new File(getFileName() + ".file");
if (!outDir.exists())
outDir.mkdir();
return outDir;
}
}