File类、字节流
-
File类
-
File类介绍
-
File:它是描述持久设备上的文件或文件夹的。只要是在Java程序中操作文件或文件夹肯定需要使用File类完成。
-
File类构造方法
/*
* File(String pathname)
* 使用 上面的这个构造方法创建的File对象,主要目的是将字符串表示的文件
* 或文件夹(目录路径)封装成File对象
*
* 在windows操作系统下,文件夹(目录路径)它们之间的分隔符""
* 而在Java中 ""它是转移字符的开始标记,因此需要书写\ 表示分隔符
* 建议后期 书写"/"
*
* File类的构造方法仅仅是将指定的字符串封装File对象,但是这个字符串表示的
* 文件或文件夹是否真实存在,在封装成File对象的时候并不会去验证
*/
File file = new File("d:\a\b\c\1.txt");
System.out.println(file);
/*
* File(String parent, String child)
* String parent :当前需要被封装的文件夹或文件所在的父目录
* String child : 当前需要封装的文件或文件夹
*/
public static void method2() {
File file = new File( "d:/" ,"1.txt");
System.out.println(file);
}
-
File的获取方法
/*
* 演示File类中的获取方法
*
* 全路径(绝对路径):
* 如果我们书写的路径包含盘符,或者是以"/" 或"\" 开始的路径,都称为全路径
* 相对路径:
* 相对路径,一般是参照当前的项目而言的路径。我们在书写路径的时候,不会书写盘符,或者 "/" 或"\"
*/
public class Demo1 {
public static void main(String[] args) throws IOException {
// 创建File对象
File file = new File("d:/");
// 演示获取的方法
// getAbsolutePath 获取封装的File对象表示的文件或文件夹的全路径 ,返回的String类型
System.out.println("getAbsolutePath="+file.getAbsolutePath());
// getAbsoluteFile 获取封装的File对象表示文件或文件夹的全路径,返回的File对象
System.out.println("getAbsoluteFile="+file.getAbsoluteFile());
// getCanonicalPath 获取到的才是真实的路径
System.out.println("getCanonicalPath="+file.getCanonicalPath());
System.out.println("getCanonicalFile="+file.getCanonicalFile());
// getName 获取到文件或文件夹的名称 ,其实获取到的是File对象中封装的最后一级内容
System.out.println("getName="+file.getName());
// getParent 获取到的是 File对象中封装的内容,不包含最后一级内容
System.out.println("getParent="+file.getParent());
// getPath 获取到File对象中封装的内容
System.out.println("getPath="+file.getPath());
// getTotalSpace 获取某个盘符的总大小
System.out.println("getTotalSpace="+file.getTotalSpace());
// getFreeSpace 获取可以使用的空间大小
System.out.println("getFreeSpace="+file.getFreeSpace());
System.out.println("getUsableSpace="+file.getUsableSpace());
}
}
-
File的创建方法(重点)
-
创建文件
-
createNewFile方法:主要是用来在指定的盘符或者目录下创建文件,如果创建的文件不存在,会创建成功,并返回true,如果创建的文件存在,返回false。
// 创建文件的方法
public static void demo1() throws IOException {
// 封装File对象
File file = new File("e:/abc/1.txt");
// 创建文件
boolean b = file.createNewFile();
System.out.println(b);
}
运行上面的代码发生异常:
注意:如果使用File类中的createNewFile方法创建文件,这时要求指定的文件所在父目录一定要存在。
-
创建文件夹(目录)
/*
* 演示File类中的创建方法
*/
public class Demo2 {
public static void main(String[] args) throws IOException{
demo3();
}
// 仅限于练习学习
public static void demo3() {
String dir = "e:/";
for( int i = 0 ; i <100 ; i++ ){
dir = dir + i + "/";
}
System.out.println(dir);
// 将多级目录封装成File对象
File dirs = new File(dir);
// 创建目录
boolean b = dirs.mkdirs();
System.out.println(b);
}
// 创建文件夹的方法
public static void demo2() {
// 将一个目录封装成File对象
File dir = new File("e:/bbb/ccc/aaaa");
/*
* 创建目录
* mkdir 创建单级目录,其实就是将File对象中最后一级目录创建成文件夹。前提是父目录必须存在
*/
boolean b = dir.mkdir();
System.out.println(b);
/*
* mkdirs 创建File中封装的多级目录
*/
boolean c = dir.mkdirs();
System.out.println(c);
}
// 创建文件的方法
public static void demo1() throws IOException {
// 封装File对象
//File file = new File("e:/1.txt");
//File file = new File("e:/abc/1.txt");
// 只要是使用createNewFile创建文件,这时就会将File对象中最后一级内容作为文件名
File file = new File("e:/abc");
// 创建文件
boolean b = file.createNewFile();
System.out.println(b);
}
}
-
File的删除方法(重点、慎用)
/*
* 演示File类中的删除方法
*/
public class Demo3 {
public static void main(String[] args) {
/*
* 封装File对象
*/
//File file = new File("e:/abc/1.txt");
File file = new File("e:/abc");
/*
* 删除文件
* delete方法是可以删除File对象中封装的文件或文件夹
* 其实删除的File对象中最后一级内容
*
* 在删除的时候一定要保证被删除的目录是空目录
*/
boolean b = file.delete();
System.out.println(b);
}
}
-
File的判断方法(重点)
我们使用File的构造方法创建出来的File对象封装的路径或文件并不一定真实存在,需要使用exists方法判断当前这个File对象表示的文件或文件夹是否存在。
一般情况下,当我们获取到一个File对象之后,需要对这个File对象进行其他操作的时候,操作之前需要先判断这个File对象表示的内容是否存在。
isDirectory :它是判断File对象封装的内容是否是文件夹(目录),我们后期经常需要判断一个File对象,如果是文件夹,就说明可以继续去获取这个文件夹下的其他文件或文件夹内容。
isFile:说明当前的File对象表示的是一个普通的文件,这时我们就可以去获取文件中具体的数据。
/*
* 演示File类中的判断方法
*/
public class Demo4 {
public static void main(String[] args) {
// 封装File对象
//File file = new File("e:/abc");
File file = new File("e:/bcd.txt");
// 判断File对象表示文件或文件夹是否存在
System.out.println(file.exists());
// 判断File对象封装的内容是否是文件夹
System.out.println(file.isDirectory());
// 判断File对象封装的内容是否是文件
System.out.println(file.isFile());
// 判断File对象封装的内容是否是隐藏内容
System.out.println(file.isHidden());
}
}
-
File的列举方法(重点)
我们有时获取到某个文件夹(目录)之后,经常需要获取这个目录下的内容(文件、文件夹)。我们就需要使用File类中的列举方法。
list:将指定目录下的所有文件和文件夹名字获取到,然后将这些名称存放在String数组中。
/*
* 演示File类中的 list方法
*/
public class Demo5 {
public static void main(String[] args) {
// 将一个目录封装成File对象
File dir = new File( "d:/" );
// 获取指定目录下的所有文件和文件夹的名称
String[] list = dir.list();
// 遍历数组
for (String s : list) {
System.out.println(s);
}
}
}
listFiles:将指定目录下的每个文件和文件夹单独再次封装成File对象,然后将这些File对象存储在File数组中。
// 演示获取某个目录下的每个文件或文件夹对象
public static void demo1() {
// 封装File对象
File dir = new File("d:/test");
// 获取指定目录下的文件和文件夹对象
File[] files = dir.listFiles();
// 遍历
for (File file : files) {
// 判断当前每个从数组中取出的File对象到底是文件还是文件夹
if( file.isDirectory() ){
System.out.println("当前的File对象是文件夹(目录)"+file.getName());
}else{
System.out.println("当前的File对象是文件"+file.getName());
}
}
}
-
获取多级目录下的内容(重点)
多级:多个目录下的内容。
// 演示获取多级目录下的内容
public static void demo2() {
// 封装File对象
File dir = new File("d:/");
getFiles(dir);
}
// 专门负责获取给定目录下的文件或文件夹对象
public static void getFiles( File dir ){
// 根据传递的文件夹获取它下面的所有文件和文件夹
File[] files = dir.listFiles();
// 遍历
for( File file : files ){
// 判断当前从数组中取出的这个File对象是否是文件夹
if( file.isDirectory() ){
// 如果是文件夹继续调用方法,获取当前这个文件夹下的所有内容
getFiles( file );
}else{
System.out.println(file);
}
}
}
上面代码可以遍历指定目录下以及子目录下的所有文件和文件夹。但是程序运行的时候,有可能发生空指针异常。
上面发生空指针异常的原因:
是因为在使用File类中的list或listFiles方法的时候,如果给定的目录Java没有权限去访问,这时list或listFiles方法将会返回null。
-
整盘扫描(不需要掌握)
-
递归技术
递归:它主要是用在函数(方法)的调用上。
递归的分类:
1、直接递归:方法自己调用自己。
2、间接递归:A方法调用B方法,B方法调用C方法........ 最后会有一个方法调用A方法。
需求:计算1~5的和值,不允许使用循环。
/*
* 使用递归技术,完成1~5的和值计算
*/
public class DiGuiDemo {
public static void main(String[] args) {
int sum = getSum( 5 );
System.out.println(sum);
}
//getSum方法使用递归完成1~5和值的计算
public static int getSum(int i) {
if( i > 1 ){
return i + getSum( i - 1 );
}else {
return 1;
}
}
}
递归细节:
-
一般书写递归的程序,要求递归中一定要有判断语句,可以保证递归能够结束。
-
即使递归中有判断,递归的次数也不能太多。
-
文件过滤器
-
文件过滤器介绍
-
过滤器:它的主要功能是将不需要的内容排除(过滤)掉。
文件过滤器:在遍历获取文件或文件夹的时候,可以对拿到的文件或文件夹进行过滤,将符合我们需求的文件或文件夹留下,不符合的全部过滤掉。
在Java中提供2个关于文件或文件夹的过滤器:
1、FilenameFilter:文件(夹)名过滤器。
2、FileFilter:文件(对象)过滤器。
-
FilenameFilter接口
上面的2个方法,都可以获取到指定目录下符合条件的文件或文件夹。符合条件的文件夹和文件需要使用方法中传递的FilenameFilter对象进行过滤。
FilenameFilter:接口中的accept方法它的主要功能是完成根据我们书写的条件进行文件或文件夹的过滤。
accept方法返回的true,就表示当前的文件或文件夹需要被留下,如果返回fasle说明当前的文件或文件夹是不需要被保留的。
/*
* 演示 使用 FilenameFilter 完成文件或文件夹的过滤
*/
public class FilenameFilterDemo {
public static void main(String[] args) {
// 封装File对象
File dir = new File( "d:/test" );
// 列出指定目录下的文件或文件夹
String[] list = dir.list( new MyFilenameFilter( ".java" ) );
// 遍历
for (String s : list) {
System.out.println(s);
}
}
}
/*
* 自己定义文件名过滤器
*/
public class MyFilenameFilter implements FilenameFilter{
// 定义成员变量,记录在创建对象的时候初始化的扩展名
private String suffix ;
public MyFilenameFilter( String suffix ){
this.suffix = suffix;
}
/*
* 解释 FilenameFilter 接口中accept方法上的两个参数
* File dir:是当前需要被过滤的文件或文件夹所在的父目录
* String name:当前需要被过滤的文件或文件夹名称
*/
public boolean accept(File dir, String name) {
// 留下 所有 名称末尾有.jpg
return name.endsWith( suffix );
}
}
-
FileFilter接口
FileFilter:它称为文件或文件夹对象过滤器。
在FileFilter过滤器中的accept方法上接收File对象,这个File对象表示的当前需要被过滤的那个文件或文件夹对象。
/*
* 演示使用 FileFilter过滤器
*/
public class FileFilterDemo {
public static void main(String[] args) {
// 封装File对象
File dir = new File("d:/test");
/*
* 获取文件或文件夹
* 需求:要求获取到指定目录下扩展名为.jpg的文件
*/
File[] files = dir.listFiles( new MyFileFilter(".jpg") );
// 遍历
for (File file : files) {
System.out.println(file);
}
}
}
/*
* 实现文件对象过滤器
*/
public class MyFileFilter implements FileFilter{
private String suffix;
public MyFileFilter( String suffix ){
this.suffix = suffix;
}
/*
* accept 方法接收的File对象是被过滤的那个文件或文件夹对象
*/
@Override
public boolean accept(File pathname) {
return pathname.isFile() && pathname.getName().endsWith(suffix) ;
}
}
-
过滤器练习
需求:找出指定目录下,以及子目录,多级目录下的.java文件。
/*
* 需求:找出指定目录下,以及子目录,多级目录下的.java文件。
*/
public class FileFilterTest {
public static void main(String[] args) {
// 封装File对象
File dir = new File("d:/test");
getFile( dir );
}
// 获取指定目录下的文件或文件夹
public static void getFile(File dir) {
/*
* 我们需要的符合条件的.java 文件,而不需要文件夹
*
* 我们在定义过滤器的时候,题目要求是获取多级目录下的扩展名为.java的文件
*
* 肯定过滤器中需要判断每个File对象是不是文件,是文件的同时还要保证扩展名是.java
*
* 但是如果当前目录下是文件夹也需要留下,因为还要进入这个文件夹中继续找有没有符合条件的文件
*
*/
File[] files = dir.listFiles( new MyFileFilter2() );
// 判断
if( files != null ){
// 遍历
for (File file : files) {
// 判断当前遍历出来的每个File对象到底是文件还是文件夹
if( file.isDirectory() ){
// 递归调用
getFile( file );
}else{
System.out.println(file);
}
}
}
}
}
public class MyFileFilter2 implements FileFilter {
@Override
public boolean accept(File pathname) {
return (pathname.isDirectory()) ||
(pathname.isFile() && pathname.getName().endsWith(".java"));
}
}
注意:如果是在遍历多级目录的时候,书写的过滤器必须保证可以留下被过滤的文件的同时要要留下当前目录下的文件夹,只有保留下文件夹才能进入子目录。如果没有保留子文件夹,最后只能遍历当前目录,无法多级目录遍历。
-
IO流技术
-
IO流的分类
-
File类,它可以操作文件或文件夹,但是它不能操作(读写)文件中的数据。
如果程序中需要读写文件中的数据,这时需要使用Java提供的专门负责读写数据的IO流对象。
IO流:以水流的方式来操作文件中的数据。在内存和我们持久设备之间如果要进行数据读写操作,那么我们就需要和持久设备之间建立数据传输的通道。在这个通道中传输的数据可以称为通道中的真正的数据。而这个数据以字节(10101001010010101)的形式传递。
File:只能操作文件或文件夹。
IO流:它是专门读写文件中的数据。
IO流对应的类或接口很多,这时我们可以按照操作的数据的特点将IO流分成:
-
字节流
-
字符流
也可以按照IO流的方向:
-
输入流
-
输出流
我们上课采用数据的特点:字节流和字符流方式学习。
数据在持久设备上全部是1010010100101 方式存储,二进制方式。8个二进制数位和在一起,恰好是一个字节。字节也是存储设备中的最小的单位。
所以我们先按照字节的方式操作。永远不会出现数据的错乱问题。
在整个IO流中,只要学会字节流的操作,其他任何流的操作规律完全一致。
-
字节流介绍
字节流:它是以字节的方式读写文件中的数据。
字节流:
字节输入流:
以字节的方式从文件中读取字节,将字节数据读取到计算机的内存(Java程序)中。
字节输出流:
以字节的方式将内存(程序)中数据写到文件中。
字节输入流:
InputStream
字节输出流:
OutputStream
IO流中公共操作行为:
在操作数据之前,肯定需要和设备之间有个数据交互的通道(其实就是让我们的Java代码可以间接和被操作的文件关联上)。记住,在操作之后,必须人为的书写代码,将我们的程序和文件之间的关联断开。
断开和文件的关联:在IO流中有一个统一的方法close。
IO流中写的方法write ,读的方法 read。
-
字节输出流
使用完流,一定要记得调用close方法,关闭资源。
write( byte[] b ) : 在调用write方法的时候,会将传递的整个byte数组中的数据写到关联的文件中。
write( byte[] b , int off , int len ) : 将byte数组中从off位置开始共计写出len个字节。
write( int b ) : 写出一个字节。
-
文件字节输出流
FileOutputStream它是OutputStream的子类,它可以直接将数据以字节的方式写到文件中。
// 写出数据
public static void demo1() throws IOException {
// 创建输出流对象 FileOutputStream(String name)
FileOutputStream fos = new FileOutputStream("e:/1.txt");
String s = "覆盖掉啦!!!";
// 写数据
fos.write( s.getBytes() );
// 关流
fos.close();
}
注意:FileOutputStream,在创建的时候,如果关联的文件不存在,它会自动的创建。如果文件存在,会覆盖掉文件中原有的数据。
如果指定的文件所在目录不存在FileOutputStream不会帮助创建,这时会直接发生异常
-
追加数据和换行
-
输出流练习
-
字节输入流
-
文件字节输入流
-
复制文件练习
-
IO流中的异常处理模版
-
输入流读取数据模版代码
-
字节流练习(切割合并文件)