一、综合练习—文件清单列表
获取指定目录下,指定扩展名的文件(含子目录),并将这些文件的绝对路径写到一个文本文件中。也就是建立一个指定扩展名的文件列表
1.深度遍历
2.过滤器->容器
3.写入文件
import java.util.List;
import java.io.*;
import java.util.ArrayList;
public class Main
{
public static void main(String[] args) throws IOException {
File dir = new File("D:\\java");//指定源文件
FilenameFilter filter = new FilenameFilter() {//过滤器
public boolean accept(File dir, String name) {
return name.endsWith(".java");
}
};
List<File> list = new ArrayList<File>();//容器
GetFile(dir, filter, list);//获取符合条件的文件
File dFile = new File(dir,"javalist.txt");
WriteToFile(list, dFile);//写入
}
/*
*
* */
public static void GetFile(File dir , FilenameFilter filter,List<File> list) throws IOException{
File[] files = dir.listFiles();
for(File file : files){
if(file.isDirectory()){
GetFile(file,filter,list);
}else{
if(filter.accept(dir, file.getName())){
list.add(file);
}
}
}
}
public static void WriteToFile(List<File> list,File destfile){
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter(destfile));
for(File file : list){
bw.write(file.getAbsolutePath());
bw.newLine();
bw.flush();
}
} catch (Exception e) {
throw new RuntimeException("写入失败");
}finally{
if(bw!=null){
try {
bw.close();
} catch (Exception e2) {
// TODO: handle exception
throw new RuntimeException("关闭失败");
}
}
}
}
}
二、IO包中的其他类
打印流:PrintWriter 、PrintStream:可以直接操作输入流和文件
序列流:SequenceInputStream:对多个流进行合并
操作对象:ObjectInputStream、ObjectOutputStream:被操作的对象需要实现Serializable(标记接口)
打印流
字节打印流:PrintStream
1.提供了打印方法可以对多种数据类型值进行打印,并保持数据的表示形式
2.永远不会抛出IOException
构造函数,接收三种类型的值
1.字符串路径
2.File对象
3.字节输出流
public static void main(String[] args) throws IOException {
PrintStream ps = new PrintStream("A.txt");//指定写入文件
//ps.write(98);//保存是b,只写入二进制的最低8位
ps.print(98);//将数据变成字符串,原样打印,每次打印都会覆盖原有数据
ps.close();
}
字符打印流:PrintWriter
构造函数,接收四种类型的值
1.字符串路径
2.File对象
3.字节输出流
4.字符输出流
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//PrintWriter pw = new PrintWriter(System.out,true)
PrintWriter pw = new PrintWriter(new FileWriter("text.txt"),true);//自动刷新,且只有输出流才会自动刷新
String line = null;
while((line=br.readLine())!=null){
if("over".equals(line))
break;
pw.println(line);
}
pw.close();
br.close();
}
序列流
SequenceInputStream
表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。
将多个源,合成一个源
构造方法:
SequenceInputStream(Enumeration<? extends InputStream> e) 通过记住参数来初始化新创建的 SequenceInputStream ,该参数必须是生成运行时类型为 InputStream 对象的 Enumeration 型参数。 |
SequenceInputStream(InputStream s1, InputStream s2) 通过记住这两个参数来初始化新创建的 SequenceInputStream (将按顺序读取这两个参数,先读取 s1 ,然后读取 s2 ),以提供从此 SequenceInputStream 读取的字节。 |
public static void main(String[] args) throws IOException {
//将a.txt,b.txt,c.txt的数据合并到一个文件
//SequenceInputStream的构造函数有两个,演示枚举
// Vector<FileInputStream> vec = new Vector<FileInputStream>();
//
// vec.add(new FileInputStream("a.txt"));
// vec.add(new FileInputStream("b.txt"));
// vec.add(new FileInputStream("c.txt"));
// Enumeration<FileInputStream> en = vec.elements();
ArrayList<FileInputStream> ar = new ArrayList<FileInputStream>();//ar下没有枚举,但是有迭代器
ar.add(new FileInputStream("a.txt"));
ar.add(new FileInputStream("b.txt"));
ar.add(new FileInputStream("c.txt"));
Enumeration<FileInputStream> en = Collections.enumeration(ar);//原理如下
/*final Iterator< FileInputStream> it = ar.iterator();
Enumeration<FileInputStream> en = new Enumeration<FileInputStream>() {//实现Enumeration
public boolean hasMoreElements() {
return it.hasNext();
}
public FileInputStream nextElement() {
return it.next();
}
};*/
SequenceInputStream sis = new SequenceInputStream(en);//合并
FileOutputStream fos = new FileOutputStream("d.txt");
byte[] by = new byte[1024];
int len = 0;
while((len = sis.read(by))!=-1){
fos.write(by,0,len);
}
fos.close();
sis.close();
}