11.1 File类
File类概念:
- File类用来进行文件的相关操作,它描述的是文件本身的属性。
- File代表的是文件或目录。
- File类创建的File对象是可以用来获取磁盘文件的相关信息。例如:权限、时间、 日期、目录路径或目录层次结构。
- File类被封装在java.io包中。
11.1.1 File 类的构造方法
例:① File file1 = new File( "F:\\112期\\code\\File类\\FileCut.java" );
② File file2 = new File( "F:\\112期\\code\\File类" , "FileCut.java" );
= new File( "F:\\112期\\code\\File类" , "\\IO流" );//child 文件名或路径
③ File f = new File( "F:\\112期\\code\\File类" );
File file3 = new File( f , "FileCut.java" ); //child 可以是文件名或路径
= new File( f , "\\IO流" );
11.1.2 访问文件和目录
11.1.3 文件过滤器
- 文件过滤方法一:自定义过滤方法
①找出指定路径下所有文件(非文件夹)
②通过file.getName().endsWith( suffix );判断file中的后缀是否与传入的suffix相同。
/**
* 自定义的文件过滤方法 filtration( File filePath , String suffix )
* @param filePath 指定文件夹路径
* @param suffix 指定过滤的后缀名,如:".java"
* @throws IOException
*/
public static void filtration(File filePath, String suffix) throws IOException {
File[] files = filePath.listFiles();
// 输出该路径下有文件、文件夹总个数
System.out.println("有文件、文件夹共 " + files.length + " 个");
// 当文件、文件夹总个数为0时,输出 "该路径下无内容!"
if (files.length != 0) {
for (File f : files) {
// 判断是否是文件
if (f.isFile()) {
// 判断f的后缀名是否与suffix相同
boolean b = f.getName().endsWith(suffix);
if (b == true) {
System.out.println(f.getAbsolutePath() + "是" + suffix + "文件");
} else {
System.out.println(f.getAbsolutePath() + "不是" + suffix + "文件");
}
} else {
System.out.println(f.getAbsolutePath() + " 是文件夹!");
}
}
} else {
System.out.println("该路径下无内容!");
}
}
(2)文件过滤方法二:文件过滤器
①定义文件过滤器类,并实现FilenameFilter接口;
②重写该接口的accept(String dir,String name )方法。dir文件路径,name文件名,在该方法中写入过滤器的要求和限制;通过file.getName().endsWith( suffix );判断file中的后缀是否与传入的suffix相同
③通过File[] files = file.listFiles( myFilter ); 将自定义过滤器的对象myFilter传入listFiles();使得其列出的所有文件和路径都符合过滤器的要求。
public static void main(String[] args) throws IOException {
//方法一:自定义的文件过滤方法 filtration( File filePath , String suffix )
//filtration(new File("F:\\笔记\\12"), ".java");
//方法二:自定义过滤器MyFilenameFilter,实现FilenameFiler接口,重写accpet()方法
//常量kiloByte代表1kb,1kb=1024字节
final long kiloByte = 1024;
MyFilenameFilter myFilter = new MyFilenameFilter( ".docx" );
//下限默认为0,上限设置为1M=1024*1024
//myFilter.setLowerSize( kiloByte*2 );
myFilter.setSuperiorSize( kiloByte*1024 );
//过滤的文件夹路径
File file = new File( "F:\\笔记" );
//在listFiles中加入 过滤器,列出的file都符合过滤器的要求
File[] files = file.listFiles( myFilter );
System.out.println( "符合过滤器要求的文件有:" );
for( File f : files ){
//逐个输出符合过滤器的文件路径名
System.out.println( f.getAbsolutePath() );
}
}
/**
* 自定义过滤器类
*/
class MyFilenameFilter implements FilenameFilter {
/**
* 要得到的文件类型,后缀名。 通过构造方法传入
*/
private String suffix;
/**
* 记录文件大小下限
*/
private long lowerSize = 0;
public long getLowerSize() {
return lowerSize;
}
public void setLowerSize(long lowerSize) {
this.lowerSize = lowerSize;
}
/**
* 记录文件大小上限
*/
private long superiorSize = 2048;
public long getSuperiorSize() {
return superiorSize;
}
public void setSuperiorSize(long superiorSize) {
this.superiorSize = superiorSize;
}
/**
* MyFilenameFilter类构造函数
* @param suffix 要筛选的后缀
*/
public MyFilenameFilter(String suffix) {
this.suffix = suffix;
}
/**
* dir 上一級目录
* name 文件的名字
*/
@Override
public boolean accept(File dir, String name) {
File file = new File( dir , name ); //先将该文件包装到File里
//如果是文件则继续执行
if( file.isFile() ){
//再判断,如果在上限与下限之间则继续执行
if( file.length() < superiorSize && file.length() > lowerSize ){
//判断文件后缀是否跟传入的是否一致,一致则返回true,否则返回false
return file.getName().endsWith( suffix );
}
}
//其中一个不符合返回false
return false;
}
}
11.1.4 文件、文件夹复制
(1)文件复制
①自定义文件复制方法 copy( String srcFilePath , String destFilePath )
参数:原文件路径名,目标文件路径名(包括文件名)
②通过IO流FileInputStream读取原文件,同时用FileOutputStream将读取到的数据 写到 目标文件。
读取并写入的代码:
//用于记录读取的数据的字节数
int readCount = 0;
//byte数组存放每次读取出来的数据,1024字节=1k
byte[] b = new byte[1024];
//判断为无数据时,返回-1
while((readCount = fis.read(b, 0, 1024)) >0 ){
//将读取到的数据写入目标文件
fos.write(b, 0, readCount);
}
(2)文件夹复制
①自定义文件夹复制方法show( File srcFolder, File destFolderPath )
参数:原文件夹路径名,目标文件夹路径(不包括文件夹名)
②将destFolderPath 并上文件夹名,即srcFolder.getName()。使用mkdirs()自动创建对应的文件夹
③通过IO流读取原文件,listFiles()获取原文件夹下所有的文件、文件夹。判断为文件夹时,递归调用show();为文件时,调用上面的文件复制方法
/**
* 文件夹的复制 show( File srcFolder, File destFolderPath )
* @param srcFolder 原文件夹路径名
* @param destFolderPath 目标文件夹路径
* @throws IOException
*/
public static void show( File srcFolder, File destFolderPath ) throws IOException{
//将 目标文件夹路径 加上 要复制的文件夹名
File newFolder = new File( destFolderPath + "\\" +srcFolder.getName() );
//调用mkdirs()使newFolder里的路径都生成对应的文件夹
boolean flag = newFolder.mkdirs();
if( flag == true ){
System.out.println( newFolder.getAbsolutePath()+" 目录创建成功" );
}else{
System.out.println( newFolder.getAbsolutePath()+" 目录创建失败" );
}
//列出File对象的所有子文件和路径,返回File数组
File[] f = srcFolder.listFiles();
for( File file : f ){
//判断是否为文件夹
if(file.isDirectory()){
//为文件夹则调用show()方法,不断递归
show( file, newFolder );x
}else{
//不为文件夹则调用copyFile方法复制文件到目标文件路径
//ps: 目标文件路径需要 加上 要复制的文件名
File newFilePath = new File( newFolder + "\\" + file.getName());
copyFile( file,newFilePath );
}
}
}
/**
* 文件复制
* @param srcFile 需要被复制的文件
* @param newFilePath 目标文件路径
* @throws IOException
*/
public static void copyFile( File srcFile ,File newFilePath) throws IOException{
boolean flag = newFilePath.createNewFile();
if(flag == true){
System.out.println(newFilePath.getAbsolutePath()+" 文件创建成功");
}else{
System.out.println(newFilePath.getAbsolutePath()+" 文件创建失败");
}
//在需要被复制的文件中读取
FileInputStream fis = new FileInputStream( srcFile );
//在需要写入文件文件的路径写入
FileOutputStream fos = new FileOutputStream( newFilePath );
int readCount = 0;
byte[] b = new byte[2048];
while((readCount = fis.read(b, 0, 2048)) >0 ){
//将读取到的数据写入目标文件
fos.write(b, 0, readCount);
}
}
11.1.5 文件切割与合并
- 文件切割
①文件切割方法cut( File parentFilePath, File childFilePath ,int blockNum, String suffixName )
参数:原文件路径名,目标文件路径,要切分块数目,分块的后缀名
②通过IO流FileInputStream读取原文件,限制每次读取的字节数,将每次读取出来的数据写入 目标文件的路径名(目标文件路径+文件名)。
注意:
- while控制读取次数的控制,将总大小不断减读取出来的字节数,直到=0为止;
- while控制每次读取文件的大小,当达到控制大小时,结束循环
- if 当读取的字节数为0时候,也结束循环
/**
* @param parentFilePath 被切割文件路径名
* @param childFilePath 切割后文件存放的路径
* @param blockNum 切割的数量
* @param suffixName 后缀名
* @throws IOException
*/
public static void cut( File parentFilePath, File childFilePath ,int blockNum, String suffixName )throws IOException{
//切割的数量
final int BLOCKNUM = blockNum;
//输入流读取
FileInputStream fis = new FileInputStream( parentFilePath );
int total = fis.available();
//获取被切割文件的总字节数
int sumSize = total;
//每个被切割块的平均字节数
int blockSize = total/BLOCKNUM;
//每次read()读取到的字节数
int redvSize = 0;
//记录各个块字节数总和
int count = 0;
//num用于作为切割后的文件命名,从1开始。。。
int num = 1;
//记录每个块的大小,用以限制切割块的大小
int starByte = 0;
byte[] b = new byte[1024];
FileOutputStream fos = null;
File newFile = null;
//sumSize不断在减小,当sumSize=0时,结束切割
while( sumSize > 0 ){
newFile = new File( childFilePath , String.valueOf(num) + suffixName );
fos = new FileOutputStream( newFile );
//在每次开始新的切割时候,double将starByte置0
starByte = 0;
//判断还没达到每个块的大小的时候,一直循环
while( starByte < blockSize ){
//每次只读取一个1024字节
redvSize= fis.read( b, 0, 1024 );
if( redvSize > 0 ){
//判断读取的字节数不大于0才执行,不大于0就break
fos.write( b, 0 ,1024 );
//总字节数不断在减少,直到减到0,外层循环也结束
sumSize -= redvSize;
//starByte每次开始切割新块都从0开始,
starByte += redvSize;
}else{
//直到该块的字节数与限定的字节数相同或者redvSize为0时才结束
break;
}
}
//count记录各块字节的总和
count += starByte;
//将num+1,num用以每一块的命名,从1开始
num++;
}
(2)文件合并
①文件合并方法combine( String srcFilePath, File combFilePath, String name, String newFileName ),参数见代码说明。
②通过IO流FileInputStream将各个文件读取出来,再用FileOutputStream写到同一个文件中。从而实现文件的合并
/**
* 文件合并方法combine( String srcFilePath, File combFilePath, String name, String newFileName )
* @param srcFilePath 多个原文件路径
* @param combFilePath 合并后文件存放路径
* @param name 合并文件的名字(不包括后缀名),各个文件名用&分隔
* @param newFileName 合并后的新文件名字(包括后缀名)
*/
public static void combine( String srcFilePath, File combFilePath, String name, String newFileName ) throws IOException{
//将被合并的文件名按照&分割开
String[] strName = name.split( "&" );
//File[]数组用于存放拆分后的各个文件名
File[] oldFile = new File[strName.length];
//将合并后文件路径名放到newFile中
File newFile = new File( combFilePath , newFileName );
//创建合并后文件
newFile.createNewFile();
//记录多个文件需要读取的总字节数
int totalSize = 0;
//记录已经读取的文件总字节数
int sum = 0;
//准备要往newFile写入数据
FileOutputStream out = new FileOutputStream( newFile );
//有几个文件需要合并就循环几次
for( int i = 0; i< strName.length; i++ ){
//设置每个需要被合并文件的路径名
oldFile[i] = new File( srcFilePath +"\\"+strName[i] );
//准备读取各个被合并文件
FileInputStream in = new FileInputStream( oldFile[i] );
//记录每个被合并文件的大小(字节数)
int total = in.available();
//记录全部被合并文件大小总字节数
totalSize += total;
//用于装读取出来的数据1024字节=1k
byte[] b = new byte[1024];
//用于装每次读取出来的字节数
int addByte = 0;
//1024字节 = 1kb ,所以每次读取1kb
while( (addByte = in.read(b, 0, 1024)) > 0 ){
out.write(b, 0, addByte);
sum += addByte; //计算总字节数
}
}
}