InputStream字节输入流
OutputStream字节输出流
用于以字节的形式读取和写入数据。
所有的数据存放在计算机中都是以数字的形式存放的。 所以字母就需要转换为数字才能够存放。
1.InputStream是字节输入流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。
FileInputStream 是InputStream子类,以FileInputStream 为例进行文件读取
public static void main(String[] args) {
try {
//准备文件好lol.txt其中的内容是AB,对应的ASCII分别是65 66
File f=new File("d:/lol.txt");
//创建基于文件的输入流
FileInputStream fis=new FileInputStream(f);
//创建字节数组,其长度就是文件的长度
byte[] all=new byte[(int) f.length()];
//以字节流的形式读取文件所有内容
fis.read(all);
for (byte b:all) {
System.out.println(b);
}
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
2.以字节流的形式向文件写入数据
OutputStream是字节输出流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。
FileOutputStream 是OutputStream子类,以FileOutputStream 为例向文件写出数据。
public class TestStream2 {
public static void main(String[] args) {
try {
//准备文件lol2.txt其中的内容是空的
File file=new File("d:/love.txt");
//准备长度是2的字节数组,用88,89初始化,其中对应的字符分别是x,y
byte data[]={88,89};//数据类型必须是byte
//创建基于文件的输出流
FileOutputStream fos=new FileOutputStream(file);
//把数据写入到输出流
fos.write(data);
//关闭输出流
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
注意:在进行读文件和写文件的时候,要注意声明数组的位置,读是后创建数组,写是先创建数组。
3.以字节流的形式向文件写入数据 中的例子,当lol2.txt不存在的时候,是会自动创建lol2.txt文件的。
但是,如果是写入数据到d:/xyz/lol2.txt,而目录xyz又不存在的话,就会抛出异常。
那么怎么自动创建xyz目录?
如果是多层目录 d:/xyz/abc/def/lol2.txt 呢?就是当文件有父目录的时候,应该怎么办?
public static void main(String[] args) {
try {
File file=new File("D:/Home/YJ/MYY/LO.TXT");
//因为默认情况下,文件系统中不存在D:/Home/YJ/MYY,所以输出会失败
//首先获取文件所在目录
File dir=file.getParentFile();
//如果该目录不存在,则创建该目录
if(!dir.exists()){
//dir.mkdir();//使用该方法会抛出异常,因为该目录的父目录也不存在
dir.mkdirs();//使用mkdirs则会把不存在的目录都创建好
}
byte data[]={89,90,91};
FileOutputStream fos=new FileOutputStream(file);
fos.write(data);
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
4.拆分文件
package stream;
import java.io.*;
import java.util.Arrays;
public class Demo03 {
public static void main(String[] args) {
int eachSize =1;//被拆分的每个文件大小为100k
File srcFile = new File("h:/l.txt");
splitFile(srcFile,eachSize);
}
/**
* 拆分的思路,先把源文件的所有内容读取到内存中,然后从内存中挨个分到子文件里
* @param srcFile 要拆分的源文件
* @param eachSize 按照这个大小,拆分
*/
private static void splitFile(File srcFile,int eachSize){
if (0 == srcFile.length())
throw new RuntimeException("长度为0,不可拆分");
//要拆分的是一个二进制文件
byte[] fileContent = new byte[(int) srcFile.length()];
//先把文件里的东西全部读取到数组中
try {
FileInputStream fis=new FileInputStream(srcFile);
fis.read(fileContent);
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
//计算需要被划分成多少份子文件
int fileNumber;
//文件是否能被整除得到的字文件个数是不一样的
//假设文件长度是25,每份的大小是5,那么就被划分成5个
//假设文件长度是26,每份的大小是5,那么就被划分成6个
if(0==fileContent.length%eachSize)
fileNumber=(int)(fileContent.length/eachSize);
else
fileNumber=(int)(fileContent.length/eachSize)+1;
//每一个文件的文件名
for (int i = 0; i <fileNumber ; i++) {
String eachFileName=srcFile.getName()+"-"+i;
//根据原文件所在的目录创建拆分后的文件
File eachFile=new File(srcFile.getParent(),eachFileName);
//拆分后的每一个文件的内容
byte[] eachContent;
//从源文件的内容里,复制部分数据到子文件
//除开最后一个文件,其他文件大小都是100k
//最后一个文件的大小是剩余的
if(i!=fileNumber-1)//不是最后一个
eachContent= Arrays.copyOfRange(fileContent,eachSize*i,eachSize*(i+1));
else//最后一个
eachContent=Arrays.copyOfRange(fileContent,eachSize*i,fileContent.length);
//写出去
try {
FileOutputStream fos=new FileOutputStream(eachFile);
fos.write(eachContent);
fos.close();
System.out.printf("输出子文件%s,其大小是 %d字节%n",eachFile.getAbsoluteFile(),eachFile.length());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
5.练习合并文件
合并文件采用另一种思路。
这种思路,不需要把所有的子文件都先读取到内存中,而是一边读取子文件的内容,一边写出到目标文件即从eclipse.exe-0开始,读取到一个文件,就开始写出到 eclipse.exe中,然后处理eclipse.exe1 eclipse.exe-2 eclipse.exe-3 … 直到没有文件可以读
package stream;
import java.io.*;
public class Demo04 {
public static void main(String[] args) {
murgeField("h:/","eclipse.exe");
}
/**
* 合并的思路,就是从eclipse.exe-0开始,读取到一个文件,就开始写出到eclipse.exe中,直到没有文件可读
* 合并前的分文件必须要和合并后的文件在一个文件夹,否则会合并失败,合并成0kB
* @param folder
* 需要合并的文件所处于的目录
* @param fileName
* 需要合并的文件的名称
* @throws java.io.FileNotFoundException
*/
private static void murgeField(String folder, String fileName) {
try {
//合并的目标文件
File destFile=new File(folder,fileName);
FileOutputStream fos=new FileOutputStream(destFile);
int index=0;
while(true){
//子文件
File eachFile=new File(folder,fileName+"-"+index++);
//如果子文件不存在了就结束
if(!eachFile.exists())
break;
//读取子文件的内容
FileInputStream fis=new FileInputStream(eachFile);
byte[] eachContent=new byte[(int) eachFile.length()];
fis.read(eachContent);
fis.close();
//把子文件的内容写出去
fos.write(eachContent);
fos.flush();
System.out.printf("把子文件%s写出到目标文件中%n",eachFile);
}
fos.close();
System.out.printf("最后目标文件的大小:%,d字节",destFile.length());
} catch (IOException e) {
e.printStackTrace();
}
}
}
多看,多理解