一、IO框架
1.IO框架介绍
IO(Input/Output)是计算机输入输出的接口。Java的核心库java.io提供了全方面的IO接口,包括:文件系统的操作,文件读写,标准设备输出等等。
java.io(File:文件和目录类、InputStream/OutputStream(抽象类):字节流读写类、Reader/Writer(抽象类):字符流读写类)
2.File类及使用
(1)一个File类的对象,表示了磁盘上的文件或目录(文件和目录路径的抽象表示形式)。
(2)File类提供了与平台无关的方法来对磁盘上的文件或目录进行操作。
(3)File类直接处理文件和文件系统。比如:删除文件、获取文件长度大小等信息。
(4)File类没有提供方法从文件读取或向文件存储信息。
(5)构造方法:
① File(String directoryPath):文件或目录的完全路径所表示的字符串
② File(String directoryPath, String fileName):文件名或目录名
③ File(File dirObj, String fileName)
(6)File类定义了获取File对象标准属性的方法。
(7)部分File类常用方法:
① public String getName();获取文件或目录的名字
② public String getParent();获取父目录的路径字符串
③ public File getParentFile();获取父目录的路径File对象
④ public String getAbsolutePath();获取文件或目录的绝对路径
⑤ public boolean exists();判断文件或目录是否存在
⑥ public File[] listFiles();获取目录中的文件和目录封装成File对象放到File数组中
⑦ public boolean isDirectory();判断是否是文件夹或目录
⑧ public long lastModified();返回文件或目录的最后一次修改的时间
⑨ public boolean isFile(); 判断是否是文件
⑩ public long length();获取文件的大小
public boolean delete();删除文件或文件夹
public boolean mkdir();创建文件夹
public File createNewFile();创建文件
说明:mkdirs()和mkdir()两个方法的区别:这两个方法都用于创建文件夹,不同的是mkdirs()可以创建嵌套文件夹,如f盘中(f:dd\\zz)即使f盘中没有dd这个文件夹它也会帮你创建,而使用mkdir()方法则不行,如果f盘中没有dd文件夹是不能创建zz这个文件夹。
public class FileDemo {
@Test
public void test01() {
// (\\)这是在windows操作系统中使用的盘符
// (/)这是在linux操作系统中使用的盘符
File file = new File("d:\\doc");
System.out.println(file.getAbsolutePath());
System.out.println(file.getParent());
System.out.println(file.isDirectory());
System.out.println(file.isFile());
System.out.println(file.exists());
System.out.println(file.length());
System.out.println(file.delete());
}
@Test
public void test02() {
// 创建文件夹
File myFile = new File("e:\\zhangsanTest");
System.out.println(myFile.mkdir());
// 删除文件首先判断是否存在,如果存在就删除不存在就创建。
File myFile2 = new File("e:\\zhangsan\\hh.txt");
if (myFile2.exists()) {
System.out.println(myFile2.delete());
} else {
try {
myFile2.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Test
public void test03() {
// 查询一个目录中的所有文件名和目录名,返回一个字符串数组。
File file = new File("e:\\");
String[] list = file.list();
for (String f : list) {
System.out.println(f);
}
}
@Test
public void test04() {
// FilenameFilter:这是文件名过滤器
// 把想要查找的文件和目录从指定的目录中过滤出来
File file = new File("e:\\zhangsan");
String[] list = file.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".txt");
}
});
for (String f : list) {
System.out.println(f);
}
}
@Test
public void test05() {
// 获得目录中的文件和目录封装成File对象,放到File数组中。
File file = new File("e:\\");
File[] listFiles = file.listFiles();
for (File f : listFiles) {
System.out.println(f.getName() + "--" + f.length());
}
}
@Test
public void test06() {
// 将想要查找的文件或目录从指定的File数组中过滤出来
File file = new File("e:\\");
File[] listFiles = file.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".txt");
}
});
for (File f : listFiles) {
System.out.println(f.getName() + "--" + f.length());
}
}
@Test
public void test07() {
// 将想要查找的文件或目录从指定的File数组中过滤出来
File file = new File("e:\\");
File[] listFiles = file.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.getName().endsWith(".txt");
}
});
for (File f : listFiles) {
System.out.println(f.getName() + "--" + f.length());
}
}
}
3.递归算法
(1)程序调用自身的编程技巧称为递归。一个过程或函数(方法)在其定义或说明中又直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可以描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。
(2)递归算法注意:
① 递归就是在过程或函数里(方法)调用自身。
② 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
public class FactorialDemo {
public static void main(String[] args) {
// 使用递归算法求5的阶乘。
System.out.println(FacUtil.getFac(5));
}
}
class FacUtil {
public static int getFac(int number) {
if (number == 1) {
return 1;
} else {
return number * getFac(number - 1);
}
}
}
4.流的概念和分类
“流”是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或是网络连接。类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流。这时候你就可以想象数据好像在这其中流动一样。来自数据源的数据流称为输入流,流向目的地的数据流称为输出流。
(1)流的分类
① 流按其流向分为“输入流”和“输出流”。(以内存为参照物,当外部的数据读到内存称之为输入流,把内存中的数据写到外部的文件中称之为输出流)
② 流按数据传输单位,分为字节流和字符流
字节流:用来读写8位二进制的字节(如MP3文件、MP4文件、多媒体文件、图片、视频都可以用字节流来进行读写操作)
字符流:用来读写16位二进制的字符(如文本文件)。
③ 流按功能分为,节点流和过滤流
节点流:用于直接操作目标设备的流。例如:磁盘或一块内存区域(直接操作数据源的流)
过滤流:是对一个已存在的流的链接和封装,通过对数据进行处理,为程序提供功能强大,灵活的读写功能。(过滤流不直接操作数据源,往往操作的是节点流,对节点流进行封装,好处是扩展节点流的功能,使它的读写功能更灵活、更强大)。
/**
* 给定一个目录,要求按层次显示目录结构信息,文件名后面加上*或\来表示文件夹。
*/
public class IteratorDirDemo {
public static void main(String[] args) {
IteratorUtil.iteratorDir(new File("e:\\学习资料"));
}
}
class IteratorUtil {
private static int level = 0;
public static void iteratorDir(File file) {
if (file != null) {
// 递归的出口,假设是文件或者是空文件夹就返回
if (file.isFile() || file.listFiles().length == 0) {
return;
} else {
File[] files = file.listFiles();
// 要求是先输出文件夹在输出文件
files = sort(files);
for (File f : files) {
StringBuilder sb = new StringBuilder();
if (f.isFile()) {
sb.append(getTab(level));
sb.append(f.getName());
} else {
sb.append(getTab(level));
sb.append(f.getName());
sb.append("\\");
}
System.out.println(sb.toString());
// 假如是文件夹
if (f.isDirectory()) {
// 进入目录遍历,层级数加1
level++;
// 递归调用遍历目录的方法
iteratorDir(f);
// 目录层级减1,返回上级目录继续打印输出
level--;
}
}
}
}
}
private static <E> File[] sort(File[] files) {
List<File> fList = new ArrayList<File>();
// 先存放文件夹(目录)
for (File file : files) {
if (file.isDirectory()) {
fList.add(file);
}
}
// 再存放文件
for (File file : files) {
if (file.isFile()) {
fList.add(file);
}
}
// 把集合中的元素转换成指定大小和指定类型的数组
return fList.toArray(new File[fList.size()]);
}
private static String getTab(int level) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < level; i++) {
sb.append("\t");
}
return sb.toString();
}
}