62,621
社区成员
发帖
与我相关
我的任务
分享import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 自定义功能的Writer , 可以随着写入文件的大小切换新文件进行输出。
*/
public class ShiftWriter extends Writer{
public static final long DEFAUT_MAX_SIZE = 1*1024*1024;
public static final String DEFAULT_CHARSET = "GBK";
/** 可计数的输出流 */
static class CounterOutputStream extends OutputStream{
private OutputStream output;
private long count=0;
public CounterOutputStream(OutputStream output) {
this.output = output;
}
@Override
public void write(int b) throws IOException {
output.write(b);
count++;
}
public long getCount() {
return count;
}
}
private long maxSize;
private File targetDir;
private int fileIndex = 1;
private String charset;
public ShiftWriter(File targetDir) throws FileNotFoundException, UnsupportedEncodingException {
this(targetDir,DEFAUT_MAX_SIZE,DEFAULT_CHARSET);
}
public ShiftWriter(File targetDir, String charset) throws FileNotFoundException, UnsupportedEncodingException {
this(targetDir,DEFAUT_MAX_SIZE,charset);
}
/**
* 构造器函数,向指定的文件夹中写入文件,文件的数据量存在最大值,达到最大值后切换文件进行写入。
* @param targetDir 目标文件夹(目录)
* @param maxSize 文件的数据最大值
* @param charset 文件采用的字符编码
*/
public ShiftWriter(File targetDir, long maxSize, String charset) throws FileNotFoundException, UnsupportedEncodingException {
if(maxSize<=0)throw new IllegalArgumentException("maxSize is wrong.");
if(targetDir==null || !targetDir.exists() || !targetDir.isDirectory()){
throw new IllegalArgumentException("target dir isn't exists.");
}
this.maxSize = maxSize;
this.charset = charset;
this.targetDir = targetDir;
File targets[] = targetDir.listFiles();
Pattern pattern = Pattern.compile("(\\d+)\\.(txt)");
for(File file : targets){
Matcher matcher = pattern.matcher(file.getName());
if(matcher.matches()){
int index = Integer.parseInt(matcher.group(1));
fileIndex = index>fileIndex?index:fileIndex;
}
}
shiftTarget();
}
private File targetFile;
private BufferedOutputStream buffer;
private CounterOutputStream counter;
private OutputStreamWriter writer;
private void shiftTarget() throws FileNotFoundException, UnsupportedEncodingException {
do{
targetFile = new File(targetDir,fileIndex+".txt");
if(targetFile.exists() && targetFile.isFile()){
if(targetFile.length()>=maxSize){
fileIndex++;
continue;
}
}
break;
}while(true);
OutputStream output = new FileOutputStream(targetFile,true);
buffer = new BufferedOutputStream(output);
counter = new CounterOutputStream(buffer);
writer = new OutputStreamWriter(counter, charset);
}
@Override
public void write(char[] cbuf, int off, int len) throws IOException {
writer.write(cbuf, off, len);
writer.flush();
if(counter.count>=maxSize){
writer.close();
buffer.flush();
buffer.close();
fileIndex++;
shiftTarget();
}
}
@Override
public void flush() throws IOException {
writer.flush();
buffer.flush();
}
@Override
public void close() throws IOException {
writer.close();
buffer.close();
}
/** 写入文件。将当前文件的数据写入到Writer中。 */
private static void writeFile(File src, Writer writer) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(src), "GBK"));
int ch = -1;
try{
while((ch=br.read())!=-1){
writer.write(ch);
}
}finally{
br.close();
}
}
/**
* 递归遍历源文件夹,将txt文件的数据写入到Writer中。
* @param dir 源文件夹
* @param level 递归深度。遍历几层文件夹。当前文件夹的值为1.
* @param writer 目标写入器(Writer)
*/
private static void mergeFiles(File dir, int level, Writer writer) throws IOException{
if(level<0)return;
if(dir.isDirectory()){
for(File file : dir.listFiles()){
mergeFiles(file, level-1, writer);
}
}
if(dir.isFile() && dir.getName().toLowerCase().endsWith(".txt")){
System.out.println(dir);
writeFile(dir, writer);
}
}
/**
* 测试用例
*/
public static void main(String[] args) throws IOException {
File srcDir = new File("d:\\tmp\\examples");
File targetDir = new File("d:\\tmp\\shift");
Writer writer = new ShiftWriter(targetDir);
try{
mergeFiles(srcDir, 2, writer);
}finally{
writer.close();
}
}
}