Java 第28讲:建立删除文件 主讲教师:李焱 讲师
内容简介 内容简介: 1.本讲的位置,教材的8章前2.5节的内容。 2.本讲的主要内容:I/O系统即输入/输出系统的概述及建立和删除文件及目录。
重点和难点 本讲内容的重点和难点 重点是掌握利用I/O类完成文件和目录的创建及删除。 难点在于牢记常用的类方法及多层目录创建或删除时的逻辑顺序。
第八章(1节)文件与流 计算机中的各类数据是存在“文件”中的;而用户对文件的操作(输入和输出)是通过java.io包中提供的类方法完成的。
8.2.1 File类概述 File类是文件和目录路径名的抽象表示形式,File类中的抽象路径名由两部分组成:第一部分为一个与系统有关的前缀字符串。第二部分为更多字符串名称的序列。除最后一个字符串外,其它字符串名称均表示一个目录,最后一个字符串名称可以表示目录也可以表示文件。File类的抽象路径名与路径名字符串之间的转化与操作系统有关。抽象路径名向实际路径名字符串转化时,每个名称与下一个名称之间由单个默认分隔符字符隔开,如Windows系统的默认分隔符是“\”。 File类的路径名又可以分为绝对路径名和相对路径名。绝对路径名是完整的路径名,相对路径名是不完整的路径名,加上当前目录路径构成绝对路径。
File的构造方法 (1) pubic File (File parent, String child) //根据parent抽象路径名再加上child路径名字符串创建File对象; (2) pubic File (String pathname) //直接根据路径字符串创建File对象; (3) pubic File(String parent, String child) //根据parent和child路径名字符串创建File对象; (4) pubic File(URI uri) //根据给定的uri(通用资源标示符,用于网络资源定位)转换成抽象路径名创建File对象。
8.2.2 File类常用方法1 (1) public boolean createNewFile() throws IOException //当且仅当不存在此抽象路径名指定的文件时,创建由此抽象路径名指定的一个新的空文件; (2) public boolean delete() //删除指定的文件或目录。若为目录,则必须为空才能删除; (3) public boolean exists() //判定指定的文件或目录是否存在; (4) public File getAbsoluteFile() //返回文件对象的绝对路径名形式; (5) public String getAbsolutePath() //返回文件对象的绝对路径名字符串; (6) public File getCanonicalFile() //返回文件对象的规范形式; (7) public String getCanonicalPath() //返回文件对象的规范路径名字符串;
File类常用方法2 (8) public String getName() //返回文件对象的文件或目录的名称; (9) public String getParent() //返回文件对象的父路径名的路径名字符串,如果此路径名没有指定父目录,则返回 null; (10) public File getParentFile() //返回文件对象的父路径名的抽象路径名,如果此路径名没有指定父目录,则返回 null; (11) public String getPath() //返回此抽象路径名转换的一个路径名字符串; (12) public boolean isDirectory() //判断指定文件是否是一个目录; (13) public boolean isFile() //判断指定文件是否是一个标准文件;
File类常用方法3 (14) public String[] list() //返回由文件对象表示的目录中的文件和目录名称所组成字符串数组; (15) public File[] listFiles() //返回一个抽象路径名数组,这些路径名表示此抽象路径名所表示目录中的文件; (16) public boolean mkdir() //创建此文件对象指定的目录; (17) public boolean mkdirs() //创建此文件指定的目录,包括创建必需但不存在的父目录; (18) public boolean renameTo(File dest) //重新命名此文件对象表示的文件; (19) public String toString() //返回此文件对象的路径名字符串。 File类提供的其它方法请读者查阅API文档。
File类方法基本应用-程序8.1-1 import java.io.*; public class E801FileOP { private File rootFile=new File("D:/TestFile"); //在给定路径下创建文件name public void creatFile(File currentFile,int name){ if(name<3){//目录最深3层 //用于显示的空格,与程序主体无关 //创建默认容量16字符的空缓冲区 StringBuffer sb=new StringBuffer(); int count=name+1; for(int i=0;i<count;i++){ sb.append(" "); }
示例程序8.1-2 //tmpFile指向一个新的文件,这个文件可能不存在 File tmpFile=new File(currentFile.getAbsolutePath()+“\\“ +String.valueOf(name)+”.txt”); //改int为字符串 System.out.println(sb+“第”+count+“级文件”+tmpFile.get AbsolutePath());//取得绝对路径 if(!tmpFile.exists()){//判断文件或目录是否存在,true在 try{tmpFile.createNewFile();//建立一个新文件 }catch(IOException e){e.printStackTrace();} } //tmpFile指向一个新的目录,这个目录可能不存在 tmpFile=new File(currentFile.getAbsolutePath()+“\\”+ String.valueOf(name));//改int为字符串 System.out.println(sb+"第"+count+"级目录:"+tmpFile. getAbsolutePath());
示例程序8.1-3 if(!tmpFile.exists()){ tmpFile.mkdirs();//建新目录name++ creatFile(tmpFile,name);//递归建目录文件 } }//if(name<3)语句结束 }//createFile()方法结束 public void delFile(File file,int num){//删目录及文件 File[] files=file.listFiles();//返回目录中文件数组 //列出目录下所有一级子目录和文件,全以File类型存储 for(int i=0;i<files.length;i++){ if(files[i].isDirectory()){//判断文件指向的是目录么 num++;//是,故目录层数加1 delFile(files[i],num);//递归删目录 }//删当前目录下的目录及文件
示例程序8.1-4 //显示的空格,与程序主体无关 StringBuffer sb=new StringBuffer(); int count=num;//得目录层数 for(int j=0;j<count;j++){ sb.append(" "); }//第num层目录,前面加num个空格 if(files[i].isDirectory()){ System.out.println(sb+"第"+count+"级目录删除:"+files[i]. getAbsolutePath());}else{ System.out.println(sb+“第”+count+“级文件删除:”+files [i].getAbsolutePath());}//if结束 files[i].delete(); //删除文件 }//for循环结束 }//delFile()方法结束
示例程序8.1-5 public E801FileOP(){//主类构造方法 System.out.println("文件根目录位于:"+rootFile. getAbsolutePath()); if(!rootFile.exists()){//若目录不存在则建立 rootFile.mkdirs();//建立根目录 } creatFile(rootFile,0);//递归建立目录及文件 System.out.println("-----------------------------------------------"); delFile(rootFile,0);//递归删除目录及文件 rootFile.delete();删除根目录 public static void main(String[] args) { new E801FileOP();
运行结果 文件根目录位于:D:\TestFile 第1级文件:D:\TestFile\0.txt 第1级目录:D:\TestFile\0 --------------------------------------------------------- 第3级目录删除:D:\TestFile\0\1\2 第3级文件删除:D:\TestFile\0\1\2.txt 第2级目录删除:D:\TestFile\0\1 第2级文件删除:D:\TestFile\0\1.txt 第1级目录删除:D:\TestFile\0 第1级文件删除:D:\TestFile\0.txt 包括根目录在内,程序结束后全被删除了。
示例解析 本例的FileOP类中定义了creatFile()和delFile()方法,并在类的构造方法中依次调用两个方法。creatFile()方法是DE盘下的TestFile文件夹中递归建立了三个文件和三个目录,若D盘下的TestFile目录不存在则首先建立此文件夹。delFile()方法是通过递归方式调用delete()方法将creatFile()方法建立的文件和目录删除。由于delete()方法在删除目录时,必须确保目录里面没有内容,否则无法正常删除,因此需要从目录的最底层文件开始删除。从结果中可以看出,delFile()方法采用递归调用的方式一直深入到最底层,从底向上删除目录。首先删除第3级目录和文件,其次是第2级,第1级。
8.2.3 I/O流概述 流可以被看成连接在数据上的“管子”,可以通过“管子”写数据和读数据。Java提供了数目繁多的“管子”。这些“管子”有一定的层次结构,如前面的图所示,其基础类是:java.io.InputStream、java.io.OutputStream、java.io.Reader、java.io.Writer、java.io.RandomAccessFile。它们都是抽象类,几乎所有的流类都继承于或间接继承于这四个类。后面的图显示出常用流之间的继承关系。
流类的基本体系图
流的分类-1 1)按照数据流的方向可以分为输入流和输出流。如8.1节所述,输入流是指从数据存储地读取数据传输到程序中,输出流是指将程序中的数据写入数据存储地。InputStream和Reader类及其子类为输入流;OutputStream和Writer类及其子类为输出流。 2)按照数据处理单位的不同可以分为字节流和字符流。字节流是以字节为单位进行处理的流,字符流是以字符为单位进行处理的流。InputStream和OutputStream类及其子类为字节流;Reader和Writer类及其子类为字符流。
字节与字符 字节,是内存长度的单位,1个字节是8位即8个bit,所以字节流是按内存长度单位来操作的; 字符,是char型的基本数据类型,1个字符的内存长度是两个字节,共16位,所以字符流是按变量来操作的,比字节流粒度大。
流的分类-2 3)按照结构层次的不同可以分为节点流和处理流。节点流是直接操作目标数据的流;处理流是在节点流的基础上不直接接触目标数据,能够更加灵活地对数据进行操作的流。直观上讲,节点流就是直接连接数据的“管子”,而处理流是套在节点流这个“管子”上的不直接接触数据的另一层“管子”,这个“管子”增加了很多新功能够进行更加灵活的操作。
流的四大抽象类 Java系统为流操作提供了四个抽象类:InputStream类、OutputStream类、Reader类和Writer类它们是几乎所有流类的父类,它们定义了许多常用的方法被用来继承或重载实现新的功能 。
1. InputStream类-输入流,字节流 (1) public int available() throws IOException //检测无阻塞条件下,下一个调用这个方法的线程所能读取的字节数; (2) public void close() throws IOException //释放资源,关闭输入流; (3) public void mark(int readlimit) //标记输入流对象的当前位置,可以用reset()方法把流重新定位到标记处; (4) public boolean markSupported() //判断此对象的mark()方法和reset()方法是否可用; (5) public abstract int read() throws IOException //读取下一字节,返回0-255之间的整数,若达到流的结尾则返回-1。此方法为抽象方法必须被重载; (6) public int read(byte[] b) throws IOException //读取最多b个字节,并写入缓冲区b,返回读入的总字节数; (7) public int read(byte[] b,int off,int len) throws IOException //功能同上一个方法类似,读取长度为len的字节数,从b[off]开始存储,返回读入的总字节数; (8) public void reset() //将流定位到最后调用mark()方法的位置,以便重新读取相同字节; (9) public long skip(long n) throws IOException //跳过和放弃n个字节,返回实际跳过的字节数。
2 OutputStream类-输出流,字节流 (1) public void close() throws IOException //释放资源,关闭输入流; (2) public void flush() throws IOException //清空输出流,写出所有缓冲的字节; (3) public void write(byte[] b) throws IOException //写出数组b中的所有字节到输出流; (4) public void write(byte[] b,int off,int len) throws IOException //写出数组b中从off位开始,个数为len的字节到输出流; (5) public abstract void write(int b) throws IOException //写出指定字节到输出流。此方法为抽象方法,必须被重载。
3 Reader类-输入流,字符流 (1) public abstract void close() throws IOException //释放资源,关闭输入流; (2) public void mark(int readAheadLimit) throws IOException //标记输入流对象的当前位置,可以用reset()方法把流重新定位到标记处。readAheadLimit为mark()方法作用的最大字符个数,超过这个个数reset()方法将失败; (3) public Boolean markSupported() //判断此对象的mark()方法和reset()方法是否可用; (4) public int read() throws IOException //读入一个字符,返回0-65535之间的整数,若达到流的结尾则返回-1; (5) public int read(char[] cbuf) throws IOException //将字符读入数组; (6)public abstract int read(char[] cbuf,int off,int len) throws IOException //将字符读入数组,读取长度为len的字符数,从b[off]开始存储; (7) public int read(CharBuffer target) throws IOException //将字符读入target字符缓冲区; (8) public boolean ready() throws IOException //判断是否准备读取此流; (9) public void reset() throws IOException //将流定位到最后调用mark()方法的位置,以便重新读取相同字符; (10) public int skip(long n) throws IOException //跳过和放弃n个字节,返回实际跳过的字符数。
4 Writer类-输入流,字符流 (1) public Writer append(char c) throws IOException //append(c)同于write(c); (2) public Writer append(CharSequence csq) throws IOException //append(csq)同于write(csq.toString()); (3) public Writer append(CharSequence csq,int start,int end) throws IOException //append(csq,start,end)同于write(csq.subSequence(start, end).toString()); (4) public abstract void close() throws IOException //释放资源,关闭输出流,该方法需要被重载。该方法需要被重载; (5) public abstract void flush() throws IOException //清空输出流,写出所有缓冲的字符,该方法需要被重载; (6) public void write(char[] cbuf) throws IOException // 写出cbuf数组中的元素到输出流; (7) public abstract void write(char[] cbuf,int off,int len) throws IOException //写出cbuf数组从off位开始个数为len的字符到输出流,该方法需要被重载; (8) public void write(int c) throws IOException //写出c中字符到输出流; (9) public void write(String str) throws IOException //写出str字符串到输出流上; (10) public abstract void write(String str,int off,int len) throws IOException //写出str字符串从off位开始个数为len的字符到输出流,该方法需要被重载。
小结 本节先讲了I/O系统类的结构,又重点讲了文件和目录的创建及删除,最后简单介绍了流操作的四大抽象类,希望大家能掌握多层目录及文件的创建和删除。
习题 1 模仿示例程序8.1,在根目录“D:\TestFile”下创建一个三级目录:目录:山东师范大学+文件:学校.txt;目录:成教学院+文件:院系.txt;目录:2014级+文件:年级.txt(以上目录是按自顶向下排列的)。要求,输入1,就创建全部目录及文件,输入0就全部删除,输入-1就退出程序。
谢谢!!再见!!