第1关:学习-Java输入输出之文件字节IO流之拆分文件
任务描述
本关任务:把给定的大文件拆分成多个小文件。
相关知识
之前我们学习了 InputStream(字节输入流)和 OutputStream (字节输出流),下面我们来了解一下它们的常用子类,FileInputStream (文件字节输入流)和 FileOutputStream(文件字节输出流)。
FileInputStream (文件字节输入流)
FileInputStream 是 InputStream 的子类,用于从文件中获取字节流。 ######构造方法 下表中是它的常用构造方法:
构造方法 | 说明 |
---|---|
FileInputStream(File file) | 通过打开一个到实际文件的连接来创建一个 FileInputStream 对象,该文件通过文件系统中的 File 对象指定 |
FileInputStream(String name) | 通过打开一个到实际文件的连接来创建一个 FileInputStream 对象,该文件通过文件系统中的路径名 name 指定 |
构造方法示例:
public static void main(String[] args) throws IOException{
// 通过File对象创建FileInputStream对象
File f = new File("C:\\Users\\yy\\Desktop\\file\\a.txt");
FileInputStream fileInputStream = new FileInputStream(f);
// 通过字符串路径直接创建FileInputStream对象
FileInputStream fileInputStream1 = new FileInputStream("C:\\Users\\yy\\Desktop\\file\\a.txt");
}
FileInputStream 的方法
下表中是它的常用方法:
方法名 | 方法说明 |
---|---|
read() | 从这个输入流读取一个字节的数据 |
read(byte b[]) | 读取字节数据放到 b 字节数组中 |
read(byte b[], int off, int len) | 从该输入流读取到字节数据,放入一个字节数组。off:数组中的起始偏移量,len:写入的字节数 |
skip(long n) | 跳过字节数 |
available() | 返回可以读取的剩余字节数的估计值 |
close() | 关闭流 |
read(byte b[]) 方法使用示例:
public static void main(String[] args) throws IOException{
// 通过File对象创建FileInputStream对象,该路径下的a.txt文件中内容为abcd
File file = new File("C:\\Users\\yy\\Desktop\\file\\a.txt");
try(
FileInputStream fileInputStream = new FileInputStream(file);){
// 创建字节数组,长度为文件长度
byte[] bytes = new byte[(int)file.length()];
// 读取字节流到数组中
int read = fileInputStream.read(bytes);
// 打印数组
System.out.print(bytes);
}
}
执行结果:
abcd
FileOutputStream (文件字节输出流)
FileOutputStream 是 OutputStream 的子类,用于将字节流写入到文件中。
FileOutputStream 的构造方法
构造方法 | 说明 |
---|---|
FileOutputStream(File file) | 通过文件对象创建 FileOutputStream 对象 |
FileOutputStream(File file, boolean append) | 如果 append 参数为 true,则将字节写入文件末尾处,相当于追加信息。如果 append 参数为 false, 则覆盖文件信息 |
FileOutputStream(String name) | 通过字符串路径创建 FileOutputStream 对象 |
FileOutputStream(String name,boolean append) | 如果 append 参数为 true,则将字节写入文件末尾处,相当于追加信息。如果 append 参数为 false, 则覆盖文件信息 |
FileOutputStream(File file, boolean append) 构造方法示例:
public static void main(String[] args) throws IOException{
// 通过File对象创建FileOutputStream对象
File file = new File("C:\\Users\\yy\\Desktop\\file\\a.txt");
FileOutputStream fileoutputStream = new FileOutputStream(file,false);
}
FileOutputStream 的方法
下表中是它的常用方法:
方法名 | 方法说明 |
---|---|
write(int b) | 将字节写入文件输出流 |
write(byte b[]) | 将字节数组写入文件输出流 |
write(byte b[], int off, int len) | 将字节数组写入文件输出流,off:数组中的起始偏移量,len:写入的字节数 |
close() | 关闭流 |
write(byte b[], int off, int len) 方法使用示例:
public static void main(String[] args) throws IOException{
// 通过File对象创建FileOutputStream对象,该路径下的a.txt文件中内容为空
File file = new File("C:\\Users\\yy\\Desktop\\file\\a.txt");
try(
FileOutputStream fileoutputStream = new FileOutputStream(file);){
// 创建字节数组,97代表小写字母a
byte[] bytes = {97,98,99,100,101};
// 将字节数组中部分数据写入文件流(从数组中下标为1的位置,取两个元素)
fileoutputStream.write(bytes,1,2);
}
}
执行结果: 文件中写入了 bc。
编程要求
仔细阅读右侧编辑区内给出的代码框架及注释,在 Begin-End 间编写程序代码,把给定的大文件拆分成多个小文件。具体要求如下:
- 接收给定的一行字符串(如:/test/a.txt。该字符串为文件路径);
- 把文件切分成 100k 大小的小文件(如果给定的文件大小小于 100k,大于 0 k,则不切分。如果给到的文件大小等于 0 k,抛出异常,输出提示语句:“文件大小为0,不可拆分”。另外,如果文件大小为 309 k,注意切分的子文件个数为 4 个);
- 切分后的子文件命名为:原文件名-n (如:test.docx-3。n 代表切分后的第几个文件,从 0 开始);
- 切分后的文件保存于原目录下。
注意:请确保抛出异常的代码位于第 15 行。
测试说明
平台将使用测试集运行你编写的程序代码,若全部的运行结果正确,则通关。
例: 测试输入:
/test/a.txt
预期输出(后台使用 ls 命令查看原文件所处目录产生的结果):
test.docx
test.docx-0
test.docx-1
test.docx-2
test.docx-3
test.docx-4
test.docx-5
test1.docx
test2.docx
test3.txt
test4.txt
开始你的任务吧,祝你成功!
源代码:
import java.io.*;
import java.util.Arrays;
import java.util.Scanner;
public class FileTest {
public static void main(String[] args) throws IOException {
// 请在Begin-End间编写完整代码
/********** Begin **********/
// 接收给定的字符串
Scanner input = new Scanner(System.in);
String str = input.next();
// 当给定文件大小等于0时,抛出异常
int each_file = 100 * 1024;
File file = new File(str);
if (file.length() == 0){throw new RuntimeException("文件大小为0,不可拆分");
}
// 把文件所有数据读取到数组中
byte[] bytes = new byte[(int)file.length()];
try (
FileInputStream fileInputStream = new FileInputStream(file);){
fileInputStream.read(bytes);
}
// 计算需要被划分成多少个子文件
int file_number;
if (bytes.length % each_file == 0){
file_number = bytes.length / each_file;
}else {
file_number = bytes.length / each_file + 1;
}
// 将读取到的数据写入到子文件中
for (int i = 0;i < file_number;i ++){
String each_fileName = file.getName() + "-" + i;
File eachFile = new File(file.getParent(), each_fileName);
byte[] eachContent;
if (file_number - 1 != i){
eachContent = Arrays.copyOfRange(bytes, each_file * i, each_file * (i + 1));}
else{
eachContent = Arrays.copyOfRange(bytes, each_file * i, bytes.length);}
try (FileOutputStream fileOutputStream = new FileOutputStream(eachFile);){
fileOutputStream.write(eachContent);
}
}
/********** End **********/
}
}