【文章标题】简单文件分割合并器的Java实现
【文章作者】曾健生
【作者邮箱】[email protected]
【作者QQ】190678908
【作者博客】http://blog.csdn.net/newjueqi
【编程环境】JDK 1.6.0_01
【作者声明】欢迎转载文章,但转载请保留文章的完整性以及注明文章的出处。
*******************************************************************************
文件分割器,有两个部分必不可少:文件分割和文件合并,下面分别阐述:
一. 文件分割
/*文件分割类,
1.通过流的形式读取源数据
2.通过定义一个固定的字节数组,实现文件分割
a,用FileInputStream读取源文件
b,通过一个字节数组作为中介存储
c,把读取到的数据写入到一个新文件
3.把原来的文件名和分割的个数写入到一个配置文件中,格式为"文件个数>文件名",选择‘>’为分割符的原因是windows中文件名不能包含‘>’,能防止和文件名重复
*/
class FileSplit
{
//文件对象
private File f;
private FileInputStream fis;
private FileOutputStream fos;
//文件名
private String fileName;
//记录分割文件的个数
int count;
//传入要分割的文件路径
FileSplit( String s )
{
f=new File( s );
fileName=s;
count=0;
}
public void split()
{
try
{
//创建一个输入流
fis=new FileInputStream( f );
//定义一个缓冲区大小256KB
byte buf[]=new byte[1024*256];
int num=0;
while( ( num=fis.read( buf ) )!=-1 )
{
//创建一个临时的分割文件对象
if( createSplitFile( buf, 0, num )==-1 )
{
return;
}
count++;
}
}
catch( IOException e )
{
e.printStackTrace();
}
finally
{
//关闭输入流
if( fis!=null )
{
try
{
fis.close();
}
catch( IOException e )
{
e.printStackTrace();
}
}
}
//创建配置文件“file.ini”,其中格式为“文件个数>文件名”
createInfoFile();
System.out.println( "文件分割成功" );
}
/*创建一个临时的分割文件对象,如果返回-1表示创建失败,程序退出
参数:buf:缓冲区
zero:读取缓冲区的开始位置
num:读取缓冲区的结束位置
*/
private int createSplitFile( byte buf[],int zero,int num )
{
//创建临时的文件对象
FileOutputStream fosTemp=null;
try
{
//生成一个独立的分割文件
fosTemp=new FileOutputStream( count+".haha" );
fosTemp.write( buf,zero,num );
fosTemp.flush();
}
catch( IOException e )
{
System.out.println( "文件"+count+".haha创建失败" );
return -1;
}
finally
{
//关闭输出流
try
{
fosTemp.close();
}
catch( IOException e )
{
e.printStackTrace();
}
}
return 1;
}
//创建配置文件“file.ini”,其中格式为“文件个数>文件名”,
//文件个数和文件名之间选择用">"分割,是因为windows中文件名不能
//有标点“>”,就能防止和后面的文件名字符有重复。
private void createInfoFile()
{
File infoFile=new File( "file.ini" );
BufferedWriter br=null;
try
{
//如果文件不存在就创建一个新的的文件
if( !infoFile.exists() )
{
infoFile.createNewFile();
}
//通过字符缓冲区写入数据
br=new BufferedWriter(
new FileWriter(infoFile) );
br.write( count+">"+fileName );
br.newLine();
br.flush();
}
catch( IOException e )
{
e.printStackTrace();
}
finally
{
if( br!=null )
{
try
{
br.close();
}
catch( IOException e )
{
e.printStackTrace();
}
}
}
}
}
二.文件合并类
/*
文件合并类
1.通过枚举获取配置文件对象
2.通过输入流获取文件个数和源文件名称
3.把各个文件对象存放在序列流中
4.把通过序列流合并成一个文件
*/
class FileMerge
{
File fileDir; //配置文件目录
FileMerge( String s )
{
this.fileDir=new File( s );
}
public void startMerge()
{
//获取配置文件对象
File f=getFile( fileDir );
//如果获取配置文件失败就返回
if( f==null )
{
System.out.println("读取配置文件失败");
return;
}
//获取文件的配置信息
String fileInfo=getFileInfo( f );
//获取文件的个数
int count=getFileCount( fileInfo );
//获取分割前的文件名
String fileName=getFileName( fileInfo );
//获取枚举集合
Vector<FileInputStream> v=getAllFile( count );
//如果集合不为空就合并文件
if( v!=null )
{
merge( v,fileName );
}
}
//获取配置文件对象
private File getFile( File fileDir )
{
File fileList[]=fileDir.listFiles();
for( int i=0; i<fileList.length; i++ )
{
if( fileList[i].getName().equals("file.ini"))
{
return fileList[i];
}
}
return null;
}
//获取文件的配置信息
private String getFileInfo( File f )
{
BufferedReader br=null;
String s=null;
try
{
//读取配置信息
br=new BufferedReader( new FileReader( f ) );
s=br.readLine();
}
catch( IOException e )
{
System.out.println( "读取配置文件失败" );
e.printStackTrace();
}
finally
{
//关闭输入流
if( br!=null )
{
try
{
br.close();
}
catch( IOException e )
{
e.printStackTrace();
}
}
}
return s;
}
//获取文件的个数
private int getFileCount( String fileInfo )
{
String num=null;
if( fileInfo!=null )
{
num=fileInfo.substring( 0,fileInfo.indexOf('>') );
}
return Integer.parseInt(num) ;
}
//获取分割前的文件名
private String getFileName( String fileInfo )
{
String fileName=null;
if( fileInfo!=null )
{
fileName=fileInfo.substring( fileInfo.indexOf('>')+1 );
}
return fileName;
}
//获取枚举集合,通过序列流进行合并,(SequenceInputStream)该流会接受一个Enumeration
private Vector<FileInputStream> getAllFile( int count )
{
Vector<FileInputStream> v=new Vector<FileInputStream>();
for( int i=0; i<count; i++ )
{
File f=null;
try
{
f=new File( fileDir, i+".haha" );
if( !f.exists() )
{
System.out.println( i+".haha文件不存在,合并失败" );
return null;
}
v.add(new FileInputStream( f ));
}
catch( IOException e )
{
e.printStackTrace();
}
}
return v;
}
//用序列流合并文件
//V为枚举接口,fileName为文件名
private void merge( Vector<FileInputStream> v ,String fileName )
{
Enumeration<FileInputStream> e=v.elements();
SequenceInputStream sis=new SequenceInputStream(e);
FileOutputStream fos=null;
byte buf[]=new byte[1024];
try
{
//创建合并后的文件
File f=new File( fileDir,fileName );
if( !f.exists())
{
f.createNewFile();
}
fos=new FileOutputStream( f );
int num=0;
//读取文件的内容
while( (num=sis.read(buf))!=-1 )
{
fos.write( buf,0,num );
fos.flush();
}
}
catch( IOException e1 )
{
e1.printStackTrace();
}
finally
{
//关闭流
try
{
sis.close();
fos.close();
}
catch( IOException e1 )
{
e1.printStackTrace();
}
}
}
}
三.小结
本程序只是简单实现了文件的分割和合并功能,有很多可以改进的地方,譬如把配置信息写入到每个分割文件中增强安全性,让用户自定义每个分割文件的大小等等。本程序只是搭建了一个很简单的框架。
文章附件下载:http://newjueqi.ys168.com/