一。File - 文件类, 可以表示文件或者目录
-
构造方法:
new File(String 文件路径)
new File(String 父路径, String 子路径)
3.路径:
绝对路径: window是 - 从盘符开始 C:\xx\xx…
Linux是 - /xx/xx (从根目录开始)
相对路径: 会有一个参照对象 a.txt
参考值: /Users/bonnie/Desktop 相对路径是: a.txt
那么a.txt的真实路径: /Users/bonnie/Desktop/a.txt
现在a.txt的真实路径: /Users/bonnie/IdeaWorks/corejava/API_day09/a.txt
那么现在的参考值: /Users/bonnie/IdeaWorks/corejava/API_day09参考值 我们称之为 - 当前目录 参考值: C:\IdeaWorks\day09\src 相对路径: com/zzxx/demo01/a.txt 那么a.txt的真实路径: C:/IdeaWorks/day09/src/com/zzxx/demo01/a.txt . : 当前目录 - 现在的参考值 ..: 上一级目录 - 现在的参考值 往上一层
@Test
public void test00Path(){
//文件路径名
String pathname = "D:\\aaa.txt";
File file1 = new File(pathname);
//通过父路径和子路径字符串
String parent = "d:\\aaa";//父路径
String child = "bbb.txt";//子路径
File file3 = new File(parent, child);
}
@Test
public void test01Path(){
// 传入文件路径, 构造File对象
// 注意: new 出来的File对象, 只是在JVM内存中有一个对象而已
// 和本地磁盘有没有这个文件, 无关 !
File file=new File("a.txt");
//获得file绝对路径 D:\JAVAmars\ioioioio\a.txt
String path=file.getAbsolutePath();
System.out.println(path);
//D:\JAVAmars\ioioioio\a.txt
//D:\JAVAmars\ioioioio参考值,a.txt相对路径
}
@Test
public void test02Path(){
File file=new File("D:\\aaa\\bbb.txt");// 绝对路径会以盘符或/开头
String path=file.getAbsolutePath();
System.out.println(path);
}
- 根据相对路径, 获得当前程序环境下的绝对路径
//通过相对路径来获取绝对路径
@Test
public void path1(){
String path=Demo1.class.getResource("b.txt").getPath();
//xx.class.getResource()获得当前包编译后的目录
// 参考值/D:/JAVAmars/out/production/ioioioio/File/+相对路径b.txt
//参考值:当前类的编译目录-就是在当前这个包的目录下
System.out.println(path);
}
@Test
public void path2(){
String path=Demo1.class.getClassLoader().getResource("File/b.txt").getPath();
// 参考值/D:/JAVAmars/out/production/ioioioio/+相对路径File/b.txt
//getClassLoader()获得当前模块的根目录
//参考值:当前模块编译后的根目录,可以理解为src下
System.out.println(path);
}
@Test
public void path3(){
String path=Demo1.class.getClassLoader().getResource("b1.txt").getPath();
// 参考值/D:/JAVAmars/out/production/ioioioio/+相对路径b1.txt
//类加载器getClassLoader()获得当前模块编译后的根目录
//参考值:当前模块编译后的根目录,可以理解为src下。因为模块下只有src里的文件会被编译。
System.out.println(path);
}
------------------------
注意:
1.xx.class.getResource("相对路径") -> 得到一个绝对路径
2.xx.class.getClassLoader().getResource("相对路径") -> 得到一个绝对路径
类路径 classpath: 就是src编译后的目录, 也叫编译根目录
以上 1 和 2 代码得到的绝对路径, 都是在编译后的目录中, 和src没有直接关系
在开发中, 我们是先将文件放入src中的, 会自动编译到类路径中
5.File常用Api
@Test
public void api1() {
File file = new File("src/File/b.txt");
File file2 = new File("a.txt");
File file3 = new File("src");
//判断文件或目录是否存在
System.out.println("文件b.txt是否存在" + file.exists());
System.out.println("文件a.txt是否存在" + file2.exists());
System.out.println("src目录是否存在" + file3.exists());
//判断文件还是目录
System.out.println("b.txt文件?" + file.isFile());
System.out.println("b.txt目录?" + file.isDirectory());
System.out.println("src文件?" + file3.isFile());
System.out.println("src目录?" + file3.isDirectory());
System.out.println("a.txt目录?" + file2.isDirectory());
System.out.println("a.txt目录?" + file2.isDirectory());
}
@Test
public void api2() throws IOException {
File file = new File("src/File/b.txt");
File file2 = new File("a.txt");
File file3 = new File("c.txt");
//创建文件
file.createNewFile();//原来就有就不会创建
file2.createNewFile();//a.txt原来没有,会创建在src下面
file3.createNewFile();//c.txt原来没有,会创建在src下面
//创建目录
File f1 = new File("lj1");
File f2 = new File("src");
File f3 = new File("lj/lj1");
//目录会创建在模块下面
f1.mkdir();
f2.mkdir();
f3.mkdirs();//创建一些目录
}
@Test
public void api3() throws IOException {
//文件
File file = new File("src/File/b.txt");
File file2 = new File("a.txt");
File file3 = new File("c.txt");
//目录
File f1 = new File("lj1");
File f2 = new File("src");
File f3 = new File("lj/lj1");
//删除文件
file3.delete();
//删除目录(只能删除空目录)
f1.delete();
f3.delete();
}
@Test
public void api4() {
File dir = new File(".");// "."表示当前module
File[] files = dir.listFiles();
for (File file : files) {
System.out.println(file);
}
System.out.println("------------------------");
File dir1 = new File("..");// ".."表示当前module的上一层。此处为工程了
File[] files1 = dir1.listFiles();
for (File file : files1) {
System.out.println(file);
}
}
@Test
public void api5() {
File dir2 = new File("/JAVAmars\\HomeWork\\src\\day01");//打印绝对路径下文件
File[] files2 = dir2.listFiles();
for (File file : files2) {
System.out.println(file);
}
}
@Test
//过滤器
public void api6() {
File file = new File(".");
//匿名内部类方式创建过滤器对象
File[] files = file.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.isFile();//判断是否为文件
}
});
System.out.println(Arrays.toString(files));
System.out.println("---------------------");
//lambda方式写过滤器
File[] files2 = file.listFiles(pathname -> {
return pathname.getName().endsWith(".txt");//判断是否。txt结尾
});
System.out.println(Arrays.toString(files2));
System.out.println("-----------------");
File[] files3 = file.listFiles(pathname -> {
return pathname.isDirectory() || pathname.isFile();
});
for (File f : files3) {
System.out.println(f);
}
}
@Test
//迭代空目录或单个文件
public void forEarch(){
File file=new File("a.text");
File[] files=file.listFiles();
System.out.println(Arrays.toString(files));//迭代单个文件的目录,会显示null的list
File file1=new File("lj1");
File[] files1=file1.listFiles();
System.out.println(Arrays.toString(files1));//迭代空目录,会得到长度为0的list
}
//自定义函数 删除目录下所有文件和目录
public void delectFile(File file) {
//删除递归结束条件:1.file对象本身就是文件。2.file是一个空目录
File[] files=file.listFiles();
if(files!=null){ //为null表示files本身就是且只有一个文件。
for(File f:files){//而空目录迭代长度为0,不会出发此处forearch
delectFile(f);
}
}
file.delete();
}
@Test
public void del(){
File file=new File("lj");
delectFile(file);//调用自定义递归删除目录下所有文件和目录
}
补充: listFiles原码
- public File[] listFiles(FileFilter filter) {
// 得到了这个目录下面所有的文件名字
String ss[] = list();
if (ss == null) return null;
// 创建了一个存储File对象的集合
ArrayList files = new ArrayList<>();
// 迭代这个名字的数组
for (String s : ss) {
// 使用文件名, 创建了一个对应的File对象
File f = new File(s, this);
if ((filter == null) || filter.accept(f))
// 当accept方法返回true, 将这个文件对象加入到list列表中
files.add(f);
}
// 将list变成数组返回
return files.toArray(new File[files.size()]);
}
二。 IO 流
-
1.以单位来分: 字节流 字符流
2.以层级来分: 底层流 包装流 -
字节流: InputStream/OutputStream
子类: FileInputStream/FileOutputStream
字符流: Reader/Writer -
注意:
1.IO所有跟文件相关的流中, 构造方法中需要File作为参数的都可以使用文件路径直接取代
2.字节流写和读都是以字节为单位的, 单个字节能不能正常显示出来, 是不确定的
字节流API:
void write(int) : 写入这个int值得低八位
int read() : 读文件中一个字节, 并且存入int的低八位, 其余空位补0
当返回 -1 的时候, 说明文件读到了末尾
@Test
public void test01Writ() throws IOException {
//如果new 的文件没有会在module下创建
/*
如果原来文件就有,想接着原来的内容后面写,构造时写true
OutputStream ot=new FileOutputStream("d.txt",true);
*/
OutputStream ot=new FileOutputStream("d.txt");
ot.write(0);//0000 0000 0000 0000
ot.write(97);
ot.write(65);
ot.write(-1);//复数的补码的最后八位为正数。所以只返回正数
//-1二进制在计算机内复数用补码表示
/*-1:原码:1000 0000 0000 0001
反码:1111 1111 1111 1110
补码 1111 1111 1111 1111
*/
ot.close();//关闭资源
}
@Test
public void test01Rread() throws IOException {
//如果文件不存在会抛出FileNotFoundException: dm.txt (系统找不到指定的文件。)
InputStream in=new FileInputStream("d.txt");
int i;
while ((i=in.read())!=-1){//read()只读低八位,且返回值为int。int32位中其他24位补0
//read读取的是文件d.txt中的内容
System.out.println("i:"+i);
}
}
@Test
public void copy() throws IOException {//复制输入流读来的内容到输出流
InputStream in=new FileInputStream("d.txt");
OutputStream ot=new FileOutputStream("a.txt");
int i;
while((i=in.read())!=-1){
ot.write(i);
}
}