IO流
IO流的第一课
一、java 的重点知识:IO流
1、IO 流用来处理设备之间的数据传输。
2、Java 对数据的操作是通过流的方式。
3、Java 用于操作流的对象都在 IO 包中。
4、流按操作数据分为两种:字节流和字符流。
5、流按流向分为:输入流和输出流。
二、IO 流常用的基类:IO 体系中的抽象类
1、字节流的抽象类:
|--InputStream
|--|--FileInputStream
|--|--|--BufferedInputStream
|--OutputStream
|--|--FileOutputStream
|--|--|--BufferedOutputStream
|--ObjectInputStream
|--PipedInputStream
2、字符流的抽象类:
|--Reader
|--|--FileReader
|--|--|--BufferedReader
|--|--|--|--InputStreamReader
|--Writer
|--|--FileWriter
|--|--|--BufferedWriter
|--|--|--|--OutputStreamWriter
字符流特点:既然 IO 流是用于操作数据的。那么数据的最常见体现形式是:文件。
3、注意:由这四个类派生出来的子类名称都是以其父类名作为子类后缀的。
如:InputStream 的子类 FileInputStream
如:Reader 的子类 FileReader
IO流的第二课
字符流和字符流缓冲区
一、字符流 FileWriter
1、找到一个专门用于操作文件的 Writer 子类对象:FileWriter (分解 FileWriter :后缀名是父类名,前缀名是该流对象的功能。)
2、FileWriter 的操作步骤:
1)、创建一个 FileWriter 对象。该对象一被初始化就必须要明确被操作的文件。而且该文件会被创建到指定的目录下。如果该目录下存在同名文件,将被覆盖。其实该步就是在D盘下创建了IOfile001.txt。
Code:FileWriter fw = new FileWriter("D:\\IOfile001.txt");
2)、调用 write 方法,将字符串写入到流中。注意:没有直接写到文件中,写入到流中(其实是写到内存中了)。
Code:fw.write("xxx");
3)、刷新流对象中缓冲中的数据。将数据刷到目的地中。
Code:fw.flush();
4)、关闭流资源,但是关闭之前会刷新一次内部缓冲中的数据,将数据刷到目的地中。close和 flush 的区别:flush 刷新后,流可以继续使用,close 刷新后,流将会关闭。
Code:fw.close();
3、把 FileWriter 定义成全局变量,供 finally 中的 close()方法。
问:为什么 close 方法要写在 finally 方法中呢?因为不再对流进行写入的时候,必须确保流的关闭。
Code:
package study.part2.day013.iostudy;
import java.io.*;
public class FileWriterDemo2 {
public static void main(String[] args) {
//把 FileWriter 定义成全局变量,供 finally 中的 close()方法
//为什么 close 方法要写在 finally 方法中呢?因为不再对流进行写入的时候,必须确保流的关闭。
FileWriter fw = null;
try{
fw = new FileWriter("D:\\IOfile002.txt");
fw.write("你好啊,哈哈哈。");
}catch(IOException ioe){
System.out.println("catch:"+ioe.toString());
ioe.printStackTrace();
}finally{
try{
//finally 中必须得对流进行不等于 null 的判断。要不然会抛出空指针异常。
if(fw!=null){
//close() 必须单独 try 一下。
fw.close();
}
}catch(IOException ioe){
ioe.printStackTrace();
}
}
}
}
4、使用 FileWriter 对已有文件的续写。给初始化的对象传递一个值为true的参数。
Code:
<p>fw = <span style="color:rgb(127,0,85);">new</span> FileWriter(<span style="color:rgb(42,0,255);">"D:\\IOfile002.txt"</span>,<span style="color:rgb(127,0,85);">true</span>);</p><p>fw.write(<span style="color:rgb(42,0,255);">"这是续写\r\n\t内容。"</span>);</p>
二、字符流 FileReader
1、常见一个文件流读取对象,和指定名称的文件相关联。要保证该文件是已经存在的,如果不存在,会发生异常:FileNotFoundException。
2、调用读取流对象的两种方法。
1)read 方法。read():一次读取一个字符。而且会自动往下读取。当读取不到数据的时候,就返回 -1 ,这时候把 -1 当中一个标记,如果返回-1,则结束读取。
Code:
FileReader fr = new FileReader("D:\\IOfile001.txt");
int ch = 0;
while((ch=fr.read())!=-1){
System.out.println("ch:"+(char)ch);
}
2)通过字符数组进行读取。
定义一个字符数组,用于存储读到的字符
该 read(char[]) 返回的是读到字符个数。
char 的长度,通常定义1024 的两倍。
Code:
FileReader fr = null;
fr = new FileReader("D:\\IOfile001.txt");
char[] chArr = new char[1024*2];
int num = 0;
while((num=fr.read(chArr))!=-1){
System.out.println("num:"+num+"---"+new String(chArr,0,num));
}
3、FileReader 与 FileWriter的测试练习
需求:将 c 盘的一个文件复制到 d 盘中。
原理:其实就是将 C 盘下的文件数据存储到 D 盘的一个文件中。
步骤:
1、在 D 盘中创建一个文件,用于存储 C 盘文件中的数据。
2、定义一个读取流,和 C 盘文件关联。
3、通过不断的读写完成数据存储。
4、关闭资源。
Code:
package study.part2.day013.iostudy;
import java.io.*;
public class FileIOCopyTest {
public static void main(String[] args) throws IOException {
copy2();
}
public static void copy2(){
FileWriter fw = null;
FileReader fr = null;
try{
fw = new FileWriter("D:\\copyInto2.txt");
fr = new FileReader("D:\\Day2017.java");
char[] chArr = new char[1024];
int num = 0;
while((num=fr.read(chArr))!=-1){
fw.write(chArr,0,num);//写入有效的数据
}
}catch(IOException ioe){
throw new RuntimeException("读取失败。");
}finally{
try{
if(fw!=null)
fw.close();
if(fr!=null)
fr.close();
}catch(IOException ioe){
ioe.printStackTrace();
}
}
}
}
上一部分了解了字符流的基本使用方法,现在,通过字符流缓冲区的方法来提高效率。
三、字节流的缓冲区。
1、缓冲区的出现提高了对数据的读写效率。
2、对应类:
|--BufferedWriter
|--BufferedReader
3、缓冲区要结合流才可以使用。
4、在流的基础上对流的功能进行了增强。
因为缓冲区的出现是为了提高流的操作效率,所以在创建缓冲区之前,必须要先有流对象。该缓冲区中提供了一个跨平台的换行符:newLine();
readLine():读行,读一行数据。readLine() 返回:包含该内容的字符串,不包含任何终止符,如果已达到流末尾,则返回 null 。
缓冲区的知识点:
1、newLine 换行:在 linux 中或者是 windows 中都是换行。记住,只要用到缓冲区,就要记得刷新。
2、关闭缓冲区,其实关闭缓冲区其实就是在关闭缓冲区的流对象。
3、真正读写操作的是 FileWriter ,所以 fw 也要操作 close 方法。
缓冲区的使用方式:
1、只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可。
BufferedWriter的示例Code:
FileWriter fw = new FileWriter("D:\\BufferedWriter.txt");
BufferedWriter bufw = new BufferedWriter(fw);
BufferedReader 的示例Code:
FileReader fr = new FileReader("D:\\BufferedWriter.txt");
BufferedReader bufr = new BufferedReader(fr);
缓冲区的练习:
需求:通过缓冲区复制一个.java文件。
Code:
package study.part2.day014.iostudy;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.io.FileWriter;
import java.io.BufferedReader;
public class BufferedTest1 {
public static void main(String[] args) throws IOException {
//创建一个读取流对象和文件关联
FileReader fr = new FileReader("D:\\IOStudyTest\\Day2017.java");
//创建一个字符写入流对象和文件关联
FileWriter fw = new FileWriter("D:\\IOStudyTest\\BufferedTest1.txt");
//创建一个读取流缓冲区,并传入fr
BufferedReader bufr = new BufferedReader(fr);
//创建一个字符写入流缓冲区
BufferedWriter bufw = new BufferedWriter(fw);
//创建一个String 对象,用来存储读取的一行字符数据
String sLine = null;
//while循环,判断,如果读取的行数不等于空,则继续循环
while((sLine=bufr.readLine())!=null){
//将循环写入缓冲区
bufw.write(sLine);
System.out.println(sLine);
bufw.flush();
}
//最后的close处理
bufr.close();bufw.close();fr.close();fw.close();
}
}
四、装饰设计模式
readLine()原理让我们明白了 BufferedReader 类中特有的方法 readLine 可以自定义一个类中包含一个功能和 readLine 一致的方法。来模拟一下 BufferedReader。
装饰设计模式:当想要对已有的对象进行功能增强时,可以定义一个类,将已有对象传入,基于已有对象的功能,并提供加强功能,那么自定义的该类就称为装饰类。装饰类通常会通过构造方法接受被装饰对象,并基于被装饰对象的功能基础上,提供更强的功能。
装饰设计模式的运用:
package study.part2.day014.iostudy;
import java.io.FileReader;
import java.io.IOException;
public class MyBufferedReaderDemo {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("D:\\IOStudyTest\\Day2017.java");
MyBufferedReder mbr = new MyBufferedReder(fr);
String sLine = null;
while((sLine=mbr.myReadLine())!=null){
System.out.println(sLine);
}
mbr.myClose();
}
}
class MyBufferedReder{
//自定义的缓冲区,将fr作为参数传入
private FileReader fr;
MyBufferedReder(FileReader fr){
this.fr = fr;
}
//自定义一个可以一次读取一行的方法
public String myReadLine() throws IOException{
//定义一个临时容器,(原BufferedReader封装的是字符串数组。)
//定义一个StringBuilder 容器。因为最终还要将数据变成字符串。
StringBuilder sb= new StringBuilder();
int ch = 0;
while((ch=fr.read())!=-1){
//判断回车符是否存在
if(ch=='\r')
continue;
if(ch=='\n')
return sb.toString();
else
sb.append((char)ch);
}
//重要的一句,如果ch=='\n',就直接返回了。由于数据还存在于缓冲区,但是未写入到sb中,所以再做一次判断
if(sb.length()!=0){
return sb.toString();
}
//最后读到文件结尾,没有数据,就返回null
return null;
}
public void myClose() throws IOException{
fr.close();
}
}
优点:装饰设计模式比继承要灵活,避免了继承体系的臃肿。而且降低了类与类之间的关系。装饰类因为增强了已有对象,具备的功能和已有的是相同的,只不过提供了更强的功能。所以装饰类和被装饰类都是属于一个体系中。
分析:
MyReader:专门用于读取数据的类
|--MyTextReader
|--MyBufferedTextReader
|--MyMediaReader
|--MyBufferedMeidaReader
|--MyDataReader//扩展
|--MyBufferedDataReader
得到MyReader 的设计:
class MyBufferedReader{
<span style="white-space:pre"> </span>MyBufferedReader(MyTextReader text){
<span style="white-space:pre"> </span><span style="font-family: Arial, Helvetica, sans-serif;">}</span>
<span style="white-space:pre"> </span>MyBufferedReader(MyMediaReader media){
<span style="white-space:pre"> </span>}
}
上面这个类就显得扩展性能极差,由于找到了其参数的共同类型:MyReader 。通过多态的形式,可以提高扩展性。
class MyBufferedReader extends MyReader{
private MyReader r;
MyBufferedReader(MyReader r){
}
}
优化后:
MyReader:专门用于读取数据的类
|--MyTextReader
|--MyMediaReader
|--MyDataReader
扩展:带行号的装饰类
FileReader fr = new FileReader("D:\\IOStudyTest\\BufferedWriter.txt");
LineNumberReader lnr = new LineNumberReader(fr);<span style="font-family: Arial, Helvetica, sans-serif;"> </span>
IO流的第三课
一、字节流和字节流缓冲区
常用于操作媒体文件,如图片,mp3等。注意:不要拿字符流来拷贝媒体文件。
字节的存储,不需要刷新,用到字节流缓冲区的时候才需要刷新等功能。
字节流最优方法Code:
public static void readFile_1() throws IOException{
FileInputStream fis = new FileInputStream("D:\\IOStudyTest\\BufferedTest1.txt");
//字节缓冲区
byte[] byt = new byte[1024*20];
int len = 0;
while((len=fis.read(byt))!=-1){
System.out.println(new String(byt,0,len));
}
fis.close();
}
练习,复制一张图片
思路:
1、用字节读取流对象和图片关联。
2、用字节写入流对象创建一个图片文件。用于存储获取到的图片数据。
3、通过循环读写,完成数据存储。
4、关闭资源。
Code:
package study.part2.day014.iostudy;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteStreamDemo2 {
public static void main(String[] args){
FileInputStream fis = null; //读取文件字节流
FileOutputStream fos = null; //保存文件字节流
try{
fos = new FileOutputStream("D:\\02.jpg");
fis = new FileInputStream("D:\\IOStudyTest\\001.jpg");
//创建字节缓冲区
byte[] buf = new byte[1024*1024];
int len = 0;
while((len=fis.read(buf))!=-1){
fos.write(buf, 0, len);
}
}catch(IOException ioe){
throw new RuntimeException("保存文件失败。");
}finally{
try{
if(fos!=null)
fos.close();
}catch(IOException ioe){
throw new RuntimeException("写入关闭失败。");
}
try{
fis.close();
}catch(IOException ioe){
throw new RuntimeException("读取关闭失败。");
}
}
System.out.println("文件Copy成功完成!");
}
//通过字节流缓冲区完成复制。
public static void copy_1() throws IOException {
BufferedInputStream bfis = new BufferedInputStream(new FileInputStream("D:\\KG\\张杰 - 剑心 - 电视剧 古剑奇谭 片头主题曲.mp3"));
BufferedOutputStream bfos = new BufferedOutputStream(new FileOutputStream("D:\\IOStudyTest\\JAVACP剑心.mp3"));
int byt = 0;
while((byt=bfis.read())!=-1){
bfos.write(byt);
}
bfis.close();
bfos.close();
System.out.println("CP完成,没有出现异常。");
}
}
二、转换流
System.out:对应的是标准的输出设备,控制台。
System.in :对应的是标准的输入设备,键盘。
readLine方法是字符流 BufferedReader 类中的方法。而键盘录入的 read 方法是字节流 InputStream 类中的方法。能不能将字节流转变成字符流再使用字符流缓冲区的 readLine 方法呢?这时候就用到转换流。
Code:
package study.part2.day014.iostudy;
import java.io.*;
public class TransStreamDemo1{
public static void main(String[] args) throws IOException {
part2();
}
public static void part2() throws IOException{
/**输入流*/
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
/**缩写:
//获取键盘录入对象。
InputStream in = System.in;
//将字节流对象转成字符流对象,使用转换流。InputStreamReader
InputStreamReader isr = new InputStreamReader(in);
//为了提高效率,将字符串进行缓冲区技术的高效操作。使用 BufferedReader
BufferedReader bufr = new BufferedReader(isr);
*/
/**输出流*/
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
/**缩写:
OutputStream out = System.out;
OutputStreamWriter osw = new OutputStreamWriter(out);
//建立缓冲区
BufferedWriter bufw = new BufferedWriter(osw);
*/
String sLine = null;
while((sLine = bufr.readLine())!=null){
//自定义键盘结束标记
if("over".equals(sLine))
break;
bufw.write(sLine.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufr.close();
bufw.close();
}
}
三、总结
1)自己的理解:高效缓冲区的使用。
文本文件操作的字符流:(将文本文件提高为字节流的操作方法,方便了文本文件的操作。)
|--BufferedReader
|--InputStreamReader
|--FileInputStream
|--BufferedWriter
|--OutputStreamWriter
|--FileOutputStream
媒体文件操作的字节流:
|--BufferedInputStream
|--FileInputStream
|--BufferedOutputStream
|--FileOutputStream
2)流操作的基本规律:
最痛苦的就是流对象有很多,不知道该用哪一个,那么使用下面方法分析
明确:(通过两个明确来完成)
1、明确数据 “源” 和 “目的”
源(目的):输入流,InputStream Reader
BufferedInputStream BufferedReader
源(目的):输出流,OutputStream Writer
2、明确操作的数据是否是 “纯文本”。
是:字符流,
不是:字节流,
3、当体系明确后,再确定要使用那个具体对象。
通过设备来进行区分:
源设备:内存,硬盘,键盘。
目的设备:内存,硬盘,控制台。
练习1:将一个图片文件中的数据存储到另一个图片文件中。【复制媒体文件】
要求按照以上格式自己完成分三个明确的分析。
源:因为是源,所以要使用读取流(输入流)。InputStream Reader
是不是操作文本文件?不是:是操作媒体文件。这个时候就不选择 Reader 了,选择 InputStream。
明确体系后:接下来明确要使用该体系中的哪个对象。
明确设备:硬盘,上的一个媒体文件。
InputStream 体系中可以操作文件的对象是 FileInputStream
FileInputStream fis = new FileInputStream("D:\\");
重点:判断是否需要提高效率?是的:加入 InputStream 体系中的缓冲区,BufferedInputStream。
BufferedInputStream bufis = new BufferedInputStream(fis);
目的:OutputStream Writer
是否是纯文本文件。否:OutputStream
设备:硬盘,媒体文件
OutputStream 体系中可以操作媒体文件对象的是 FileOutputStream
FileOutputStream fos = new FileOutputStream();
重要:判断是否需要提高效率?是的:加入 OutputStream 体系中的缓冲区BufferedOutputStream
BufferedOutputStream bufos = new BufferedOutputStream(fos);
3)扩展:
打印系统属性信息:以键值对的形式存入文件中
package study.part2.day014.iostudy;
import java.io.*;
import java.util.Properties;
public class SystemInfo {
public static void main(String[] args) throws IOException {
Properties prop = System.getProperties();
//System.out.println(prop);
PrintStream ps = new PrintStream("D:\\IOStudyTest\\SystemInfo.log");
//prop.list(System.out);
prop.list(ps);
}
}
异常信息的日志记录:
package study.part2.day014.iostudy;
import java.io.IOException;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExceptionInfo {
public static void main(String[] args) throws IOException {
try{
int[] iArr = new int[2];
System.out.println(iArr[4]);
}catch(Exception e){
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateTime = sdf.format(d);
PrintStream ps = new PrintStream("D:\\IOStudyTest\\Exception.log");
ps.println(dateTime);
System.setOut(ps);
e.printStackTrace(System.out);
}
}
}<span style="font-family: Arial, Helvetica, sans-serif;"> </span>
IO流的第四课
一、File 类
1)File 类(操作系统中的各种文件或文件夹,如txt文件,文件夹)
1、用来将文件或者文件夹封装成对象。
2、方便对文件与文件夹的属性信息进行操作。
3、File 对象可以作为参数传递给流的构造函数。
4、了解 File 类中的常用方法。
关于流的特性:只能操作数据。
2)File 类的常见方法:
1、创建。
boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false。和输出流不一样,输出流对象一建立创建文件。而且文件已经存在,会覆盖。
boolean mkdir():创建一级文件夹。
boolean mkdirs():创建多级文件夹。
2、删除。
boolean f.delete();删除失败时返回false。
void f.deleteOnExit();在程序退出时删除指定文件。
3、判断。
boolean f.canExceute:文件是否可执行。.java文件可以执行,.txt文件就不行了。
boolean exists():文件是否存在。【重点】
boolean isDirectory():判断是否是目录
boolean isFile():判断是否是文件
boolean isHidden():判断文件是否是隐藏文件
boolean isAbsolute():判断是否是绝对路径
4、获取信息。
String getName():获取名称。
String getPath():相对路径。
String getParent():获得父目录。
String getAbsolutePath():绝对路径。
long lastModified():返回时间。
long length():返回长度。
File.pathSeparator: 返回当前系统的路径分隔符,默认为 “;”。
File.Separator:返回当前系统的目录分隔符,windows默认为 “\”。
5、重命名
boolean renameTo(File dest):可以实现移动的效果。剪切+重命名。
3)File 的使用注意点:
1、初始化一个文件对象,但是该对象并未被创建,创建的方法应该对象.createNewFile()。
2、在判断文件对象是否是文件或者目录的时候,必须要先判断该文件对象封装的内容是否存在。
3、File.separator目录分隔符,起到跨平台的作用,因为 windows 下的转义符 “ \ ” 可能在 linux 下就无法正常读取。
4、使用File 的方式删除(delete())。该方法不可随便乱删。这个方法删除文件是直接清除,并非放回收站。
Code:
package study.part2.day015.iostudy;
import java.io.File;
import java.io.IOException;
public class FileDemo1 {
public static void main(String[] args) throws IOException {
method_5 ();
}
public static void method_5(){
File f1 = new File("D:\\IOStudyTest\\copyInto.txt");
File f2 = new File("D:\\IOStudyTest\\copyIntoRename.txt");
sop("rename:"+f1.renameTo(f2));
}
public static void method_4(){
//初始化一个文件对象,但是该对象并未被创建(createNewFile)
File f = new File("D:\\IOStudyTest\\file002.txt");
sop("path:"+f.getPath()); //返回的是
sop("absPath:"+f.getAbsolutePath());
//该方法返回的是绝对路径中的父目录。
//如果获取的是相对路径,则返回null。
//如果相对路径中有上一层目录那么该目录就是返回结果。
sop("parent:"+f.getParent());
}
//重点————————————
public static void method_3() throws IOException{
//初始化一个文件对象,但是该对象并未被创建(createNewFile)
File f = new File("D:\\IOStudyTest\\file002.txt");
//f.createNewFile();
//f.mkdir();创建了【file002.txt】文件夹。。。。。
//记住,在判断文件对象是否是文件或者目录的时候,必须要先判断该文件对象封装的内容是否存在。
//通过 exists 判断
sop("dir:"+f.isDirectory());
sop("file:"+f.isFile());
//文件的隐藏属性
sop(f.isHidden());
//判断是否是绝对路径
sop(f.isAbsolute());
}
public static void consMethod(){
//File 方法封装的只是路径,并不能代表什么
//方法1:将 a.txt 封装成 file 对象。可以将已有的和未出现的文件或者文件夹封装成对象,
File f1 = new File("a.txt");
//方法2: 文件目录 文件名
File f2 = new File("D:\\IOStudyTest","XX.txt");
//方法3:
File d = new File("D:\\IOStudyTest");
File f3 = new File(d,"xx.txt");
sop("f1:"+f1);
sop("f2:"+f2);
//目录分隔符,起到跨平台的作用,因为 windows 下的转义符 “ \ ” 可能在 linux 下就无法正常读取
//所以 File.separator 就起到了这个作用。
File f4 = new File("D:"+File.separator+"IOStudyTest"+File.separator);
}
public static void method_1() throws IOException{
//初始化一个文件对象(并未创建)
File f = new File("D:\\IOStudyTest\\file1.txt");
//告诉虚拟机,等你退出的时候,帮我把它删了
f.deleteOnExit();
//createNewFile():对初始化的文件对象进行创建文件
sop("create:"+f.createNewFile());
//sop("delete:"+f.delete());
}
public static void method_2(){
File f = new File("D:\\IOStudyTest\\file1.txt");
sop("execute:"+f.canExecute());
//创建文件夹,mkdir只能创建一级目录
File mkdir = new File("D:\\IOS");
sop("mkdir:"+mkdir.mkdir());
}
public static void removeDir(File dir){
File[] files = dir.listFiles();
for(int x = 0;x<files.length;x++){
//删除非隐藏文件
if(!files[x].isHidden()&&files[x].isDirectory()){
removeDir(files[x]);
}
System.out.println(files[x].toString()+"-files-"+files[x].delete());
}
System.out.println(dir+"-dir-"+dir.delete());
}
public static void sop(Object obj){
System.out.println(obj);
}
}
4)FileList
1、注意:调用 list 方法的 file 对象必须是封装了一个目录。该目录还必须是存在的。
2、dir.listFiles():列出指定目录下的文件或者文件夹,包含子目录中的内容。也就是列出指定目录下的所有内容。因为目录中还有目录,只要使用同一个列出目录功能的函数,即可。
3、递归 :在列出过程中出现的还是目录的话,可以再次调用本功能,也就是函数自身调用自身,这种表现形式(编程手发)称为递归。
4、FilenameFilter:文件过滤器。重写 FilenameFilter 接口中的accept 方法创建一个字符串数组,用来存储文件地址中的文件的名称。用匿名内部类的使用方式,用来过滤文件。
5、FileList练习:将一个指定目录下的java 文件的绝对路径,存到一个文本文件中。建立一个 java 文件列表。
解题思路:
1、对指定的目录进行递归。
2、递归过程中,所有的java 文件的路径。
3、将这些路径存储到集合中。
4、将集合中的数据写入到一个文件中。
Code:
package study.part2.day015.iostudy;
import java.util.*;
import java.io.*;
public class FileListTest1 {
public static void main(String[] args) throws IOException {
File dir = new File("D:\\IOStudyTest");
List<File> list = new ArrayList<File>();
fileToList(dir,list);
System.out.println(list.toString());
writeToFile(list);
}
public static void fileToList(File dir,List<File> list){
File[] files = dir.listFiles();
for(File file : files){
if(file.isDirectory()){
fileToList(file,list);
}else{
if(file.getName().endsWith(".java"))
list.add(file);
}
}
}
public static void writeToFile(List<File> list) throws IOException{
BufferedWriter bufw = null;
try{
bufw = new BufferedWriter(new FileWriter("D:\\IOStudyTest\\JAVA_Directory.txt"));
String path = "";
for(File f : list){
path = f.getAbsolutePath();
bufw.write(path);
bufw.newLine();
bufw.flush();
}
}catch(IOException ioe){
ioe.printStackTrace();
}finally{
if(bufw!=null)
bufw.close();
}
}
}