文件的拆分与合并

题目

FileHelper.java

package bytes;

import java.io.File;

public final class FileHelper {
	
	/**
	 * 将第一个参数传入的文件拆分后依次序存储到第二个参数对应的目录下
	 * @param file 被拆分的源文件
	 * @param path 拆分后的问价存储路径
	 * @param size 表示每个小文件的最大体积
	 */
	public static void split( File file , File path , int size ) {
		
		if( !file.exists() || !file.isFile() ) {
			throw new IllegalArgumentException( "被拆分的文件不存在" );
		}
		
		if( !path.exists() || !path.isDirectory() ) {
			throw new IllegalArgumentException( "目标位置不存在或不有效目录" );
		}
		
		// 从 file 所表示的文件中读取数据,每次读取 50MB ,写出到一个新文件中
		// 假设大文件名称为 阿凡达.mp4 ( 1576MB ) ,则拆分后的文件为 "阿凡达01" 、 "阿凡达02" ...
		
	}
	
	/**
	 * 将第一个参数传入的目录中有序的文件合并到一个大文件( 第二个参数表示合并后的文件的存储位置 )
	 * @param path 依次序存放了一批等待合并的小文件的目录
	 * @param dest 合并之后的大文件的存储路径
	 */
	public static void join( File path , File dest ) {
		
	}

}

Myself

FileHelper.java

package bytes;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public final class FileHelper {
	
	/**
	 * 将第一个参数传入的文件拆分后依次序存储到第二个参数对应的目录下
	 * @param file 被拆分的源文件
	 * @param path 拆分后的文件存储路径
	 * @param size 表示每个小文件的最大 体积
	 * @throws IOException 
	 */
	public static void split( File file , File path , int size ) throws IOException {
		
		if( !file.exists() || !file.isFile() ) {
			throw new IllegalArgumentException( "被拆分的文件不存在" );
		}
		
		if( !path.exists() || !path.isDirectory() ) {
			throw new IllegalArgumentException( "目标位置不存在或不有效目录" );
		}
		
		// 从 file 所表示的文件中读取数据,每次读取 size byte大小 ,写出到一个新文件中
		// 假设大文件名称为 阿凡达.mp4 ( 1576MB ) ,则拆分后的文件为 "阿凡达01" 、 "阿凡达02" ...
		
		long count = file.length()/size; // 计算文件可被分为多少份
		count =( (file.length()%size==0) ? count : count+1 ) ;
		
		String name = file.getName(); // 获取源文件的文件名
		int index = name.lastIndexOf("."); // 返回.在name字符串中第一次出现的位置
		String prefix = "";
		String suffic = "";
		if(index>0) {
			prefix = name.substring(0,index); // 返回源文件文件名的前缀,截取[0,index)
			suffic = name.substring(index); // 返回后缀,截取[index,最后一位]
		}else {
			prefix = name ;
		}
		
		byte[] buffer = new byte[size];
		InputStream in = new FileInputStream(file); // 用于读取 file 对应文件	
		File src=null;
		OutputStream out =null;
		
		for( int i = 1; i <= count ; i++ ) {
			
			int x = in.read(buffer); // 从字节输入流中读取数据到buffer数组中,返回实际读取的有效字节数
			
			/*String filename =path +"/"+ prefix + ( i<10 ? "0"+i :i) + suffic ;
			src = new File(s);*/
			String filename = prefix + (i<10?"0"+i:i) + suffic;
			src = new File(path,filename);
			
			out = new FileOutputStream(src); // 以覆盖方式向 src表示的目录下 追加数据
			out.write( buffer , 0, x ) ; // 将buffer数组中[0,x)之间的字节写入输出流(写入读到的有效的字节)
		
		}
		
		in.close();	
		out.close();
		
	}
	
	/**
	 * 将第一个参数传入的目录中有序的文件合并到一个大文件( 第二个参数表示合并后的文件的存储位置 )
	 * @param path 依次序存放了一批等待合并的小文件的目录
	 * @param dest 合并之后的大文件的存储路径
	 * @throws IOException 
	 */
	public static void join( File path , File dest ) throws IOException {
		if( !path.exists() || !path.isDirectory() ) {
			throw new IllegalArgumentException( "目标位置不存在或不是有效目录" );
		}
		if( !dest.exists() || !dest.canWrite() ) {
			throw new IllegalArgumentException( "目标位置不存在或没有写权限" );
		}
		
		//对path目录下的小文件进行过滤,并放在files实例数组中
		FileFilter fileFilter = new FileFilter() {
			@Override
			public boolean accept( File pathname ) {
				return pathname.isFile() ;
			}
		};
		File[] files = path.listFiles(fileFilter);
		
		// 获得path目录下每个小文件的文件名
		String[] smallName = new String[files.length];
		String suffic = null;
		for( int i = 0 ; i < files.length ; i++ ) {
			
			smallName[i] = files[i].getName(); 	
			int index = smallName[i].lastIndexOf(".");
			if(index>0) { // 取前缀和后缀
				suffic = smallName[i].substring(index);
				smallName[i] = smallName[i].substring(0,index);	
			}
				
		}
		
		// 开始对path目录下的小文件根据文件名进行排序
		String temp="";
		for( int i = 0 ; i < files.length-1 ; i++ ) {
			for ( int j = 0 ; j < files.length-1-i ; j++ ) {
				if( smallName[j].compareTo(smallName[j+1]) >0) {
					temp = smallName[j];
					smallName[j] = smallName[j+1];
					smallName[j+1] = temp;
				}
			}
		}
		
		// 将排好序的小文件名,与父目录一起,重新赋给files实例数组
		for( int i = 0 ; i < files.length ; i++ ) {
			files[i] = new File(path,smallName[i]+suffic);
		}
		
		// 创建src实例,代表合并之后的大文件的完整存储路径
		File src = new File( dest , smallName[0]+suffic); 
		
		// 开始合并
		InputStream in = null ;
		byte[] buffer =null;
		OutputStream out = new FileOutputStream(src,true);	
		
		for( File item : files ) {
			int len = (int)item.length();
			buffer = new byte[len];
			in = new FileInputStream(item);
			int x = in.read(buffer);
			out.write(buffer,0,x);
		}
		in.close();
		out.close();
	}

	public static void main(String[] args) throws IOException {
        // 运行时是在Eclipse环境下,当前目录为Eclipse的工程文件
		File file = new File("阿凡达.txt"); // file路径为:当前目录下的 阿凡达.txt文件
		File path = new File("smalldir"); // path路径为:当前目录下的 smalldir目录
		if(!path.exists()) {
			path.mkdir();  // 如果没有smalldir目录,则创建此目录,若没有此步骤,则出现NullPointerException
		}
		File dest = new File("bigfile"); // dest路径为:当前目录下的 bigfile2目录
		if(!dest.exists()) {
			dest.mkdir();
		}
		FileHelper.split(file,path,1024); // 拆分
		FileHelper.join(path, dest); // 合并
	}
	
}

Teacher

测试数字格式化

NumberTest.java
package bytes;

import java.text.DecimalFormat;
import java.text.NumberFormat;

public class NumberTest {

	public static void main(String[] args) {
		
		String name = "阿凡达.mp4";
		int index = name.indexOf( "." );
		
		String x = name.substring( 0 , index );
		System.out.println( "原点之前: " + x );
		
		String y = name.substring( index );
		System.out.println( "原点之后: " + y );
		
		for( int i = 1 ; i <= 17 ; i++ ) {
			System.out.println( x + ( i < 10 ? ( "0") + i : i ) );
		}
		
		System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
		
		NumberFormat nf = new DecimalFormat( "00" );
		
		for( int i = 1 ; i <= 17 ; i++ ) {
			System.out.println( x + nf.format( i ) );
		}
		
		final int size = 1 << 20 ;
		System.out.println( size );

	}

}

FileHelper.java

package bytes;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;

public final class FileHelper {
	
	/**
	 * 将第一个参数传入的文件拆分后依次序存储到第二个参数对应的目录下
	 * @param file 被拆分的源文件
	 * @param path 拆分后的问价存储路径
	 * @param size 表示每个小文件的最大体积
	 */
	public static void split( File file , File path , int size ) throws IOException {
		
		if( !file.exists() || !file.isFile() ) {
			throw new IllegalArgumentException( "被拆分的文件不存在" );
		}
		
		if( !path.exists() || !path.isDirectory() ) {
			throw new IllegalArgumentException( "目标位置不存在或不有效目录" );
		}
		
		// 获取文件体积
		final long length = file.length(); 
		// 获取原文件名
		final String name = file.getName();
		
		String prefix = "" ;
		String suffix = "" ;
		
		int index = name.indexOf( "." );
		if( index > 0 ) {
			prefix = name.substring( 0 , index );
			suffix = name.substring( index );
		} else {
			prefix = name ;
		}
		
		// 统计拆分后的文件数
		long n = length / size;
		if( length % size != 0 ) {
			n++ ; 
		}
		
		InputStream in = new FileInputStream( file );
		
		final byte[] bytes = new byte[ size ];
		
		for( int i = 1 ; i <= n ; i++ ) {
			// 暂时不考虑 n > 99 的情况
			String filename = prefix + "#" + ( i < 10 ? ( "0" + i ) : i ) + suffix ;
			
			int x = in.read( bytes ); // 从 字节输入流 中读取数据到 bytes 数组中并返回实际读取到的有效字节数
			
			File dest = new File( path , filename );
			OutputStream out = new FileOutputStream( dest );
			out.write( bytes ,  0 , x ); // 将 bytes 数组中 [ 0 , x ) 之间的字节写入到输出流中
			out.close();
		}
		
		// 从 file 所表示的文件中读取数据,每次读取 50MB ,写出到一个新文件中
		// 假设大文件名称为 阿凡达.mp4 ( 1576MB ) ,则拆分后的文件为 "阿凡达01" 、 "阿凡达02" ...
		
		in.close();
		
	}
	
	/**
	 * 将第一个参数传入的目录中有序的文件合并到一个大文件( 第二个参数表示合并后的文件的存储位置 )
	 * @param path 依次序存放了一批等待合并的小文件的目录
	 * @param dest 合并之后的大文件的存储路径
	 */
	public static void join( File path , File dest ) {
		
		if( !path.exists() || !path.isDirectory() ) {
			throw new IllegalArgumentException( "目录不存在或不有效目录" );
		}
		
		File destParent = dest.getParentFile();
		
		if( !destParent.exists() || !destParent.canWrite() ) {
			throw new IllegalArgumentException( "目标位置的父目录不存在" );
		}
		
		FileFilter fileFilter = new FileFilter() {
			@Override
			public boolean accept(File pathname) {
				return pathname.isFile() ;
			}
		};
		
		File[] files = path.listFiles( fileFilter ); // 可以考虑使用 FileFilter 对文件进行过滤
		System.out.println( Arrays.toString( files ) );
		
		// 使用 比较器 对 files 数组中的元素按照 文件名称进行排序
		
		// 排序之后再考虑合并
		
	}

}

FileHelperTest.java

package bytes;

import java.io.File;
import java.io.IOException;

public class FileHelperTest {

	public static void main(String[] args) throws IOException {
		
		File file = new File( "沧海一声笑.mp3" ) ;
		
		File path = new File( "split" ) ;
		if( !path.exists() ) { // 如果不存在的话
			path.mkdir(); // 创建单层次目录
		}
		
		int size = 1 << 20 ; // 1M = 1024kb , 1kb = 1024 bytes.
		
		FileHelper.split( file , path , size);

	}

}

Others

FileHelper.java

package iostream;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public final class FileHelper {

	/**
	 * 将第一个参数传入的文件拆分后依次序存储到第二个参数对应的目录下
	 * 
	 * @param file 被拆分的源文件
	 * @param path 拆分后的问价存储路径
	 * @param size 表示每个小文件的最大体积
	 */
	public static void split(File file, File path, int size) throws IOException {

		if (!file.exists() || !file.isFile()) {
			throw new IllegalArgumentException("被拆分的文件不存在");
		}

		if (!path.exists() || !path.isDirectory()) {
			throw new IllegalArgumentException("目标位置不存在或不有效目录");
		}

		// 从 file 所表示的文件中读取数据,每次读取 50MB ,写出到一个新文件中
		// 假设大文件名称为 阿凡达.mp4 ( 1576MB ) ,则拆分后的文件为 "阿凡达01" 、 "阿凡达02" ...
		InputStream in = new FileInputStream(file);
		OutputStream out = null;
		String name = file.getName().substring(0, file.getName().lastIndexOf("."));
		String exp = file.getName().substring(file.getName().indexOf("."));
		String filename = "";
		int flag = 1;
		int n;
		byte[] buffer = new byte[size];
		while ((n = in.read(buffer)) != -1) {
			if(flag < 10) {
				 filename = path + "\\" + name + 0 + flag + exp;
			}else {
				 filename = path + "\\" + name + flag + exp;
			}
			String s = new String(buffer, 0, n);
			out = new FileOutputStream(filename);
			out.write(s.getBytes());
			flag++;
			out.close();
		}
		in.close();
	}

	/**
	 * 将第一个参数传入的目录中有序的文件合并到一个大文件( 第二个参数表示合并后的文件的存储位置 )
	 * 
	 * @param path 依次序存放了一批等待合并的小文件的目录
	 * @param dest 合并之后的大文件的存储路径
	 * @throws IOException 
	 */
	public static void join(File path, File dest) throws IOException {
		
		if( !path.exists() || !path.isDirectory() ) {
			throw new IllegalArgumentException( "合并的文件目录不存在" );
		}
		
		if( !dest.exists() || !dest.isDirectory() ) {
			throw new IllegalArgumentException( "合并文件存储路径不存在或不有效目录" );
		}

		
		File[] file=path.listFiles();
		String name = file[0].getName().substring(0,file[0].getName().lastIndexOf("0"));
		String exp = file[0].getName().substring(file[0].getName().indexOf("."));
		String destname = dest + "\\" + name + exp;
		
		for(int i=0;i<file.length;i++) {
			InputStream in=new FileInputStream(file[i]);
			int size=(int)file[i].length();
			byte[] buffer=new byte[size];
			int n=0;
			while((n=in.read(buffer))!=-1) {
				String s = new String(buffer, 0, n);
				OutputStream out=new FileOutputStream(destname, true);
				out.write(s.getBytes());
				out.close();
			}
			in.close();
			
		}

		
	}

}

HelperTest.java

package iostream;

import java.io.File;
import java.io.IOException;

public class HelperTest {

	public static void main(String[] args) throws IOException {
		
		File fod = new File("src\\iostream\\test.txt");
		File path = new File("src\\files");

		FileHelper.split(fod, path, 50);
		
		File dest=new File("src\\filesjoin");
		FileHelper.join(path, dest);
		
	}

Java可以通过IO流来实现大文件拆分合并。 首先,对于大文件拆分,可以通过RandomAccessFile类来实现,该类提供了seek()和read()方法,可以指定读取文件的位置和读取的字节数。可以根据需求将大文件拆分成多个小文件,每个小文件的大小相同或者不同。 对于大文件合并,可以通过FileInputStream和FileOutputStream类来实现。可以将多个小文件按照指定的顺序读取并写入到一个大文件中。需要注意的是,在写入时需要使用追加模式,避免覆盖已有的文件内容。 下面是一个简单的例子,实现了将大文件拆分成多个小文件和将多个小文件合并成一个大文件的功能: ```java import java.io.*; public class FileUtil { //拆分文件 public static void splitFile(String filePath, int splitSize) throws IOException { File file = new File(filePath); if (!file.exists() || file.isDirectory()) { throw new IOException("文件不存在或者是一个目录"); } long fileSize = file.length(); int fileNum = (int) Math.ceil((double) fileSize / splitSize); byte[] buffer = new byte[1024]; int len; try (RandomAccessFile raf = new RandomAccessFile(file, "r")) { for (int i = 0; i < fileNum; i++) { String fileName = file.getName() + "." + (i + 1); try (FileOutputStream fos = new FileOutputStream(fileName)) { int count = 0; while ((len = raf.read(buffer)) != -1) { fos.write(buffer, 0, len); count += len; if (count >= splitSize) { break; } } } } } } //合并文件 public static void mergeFile(String destPath, String... sourcePaths) throws IOException { File destFile = new File(destPath); if (destFile.exists()) { destFile.delete(); } try (FileOutputStream fos = new FileOutputStream(destFile, true)) { for (String sourcePath : sourcePaths) { File sourceFile = new File(sourcePath); if (!sourceFile.exists() || sourceFile.isDirectory()) { throw new IOException("文件不存在或者是一个目录"); } try (FileInputStream fis = new FileInputStream(sourceFile)) { byte[] buffer = new byte[1024]; int len; while ((len = fis.read(buffer)) != -1) { fos.write(buffer, 0, len); } } } } } } ``` 使用方法: ```java //拆分文件 FileUtil.splitFile("test.txt", 1024 * 1024); //合并文件 FileUtil.mergeFile("test_merge.txt", "test.txt.1", "test.txt.2", "test.txt.3"); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值