文章目录
IO 中一些概念学习
学习 File 之前我们先了解一些概念。
什么是IO
IO 是指对数据流的输入和输出(相对于内存来说),也称为 IO 流。
流的概念和作用
IO流的本质是数据传输,并且流是单向的。流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在设备间传输称之为流。
IO流的分类
· 根据数据处理的不同类型分为:字节流和字符流。字节流可以处理任何类型的数据,如图片,视频等,字符流只能处理字符类型的数据。
· 根据数据流向不同分为:输入流和输出流。对于输入流只能进行读操作。对于输出流只能进行写操作。
程序中需要对于传输数据的不同特性而使用不用的流。
字符流和字节流
按照“流”中处理数据的单位,可以将其区分为:字节流和字符流。在 java 中,字节是占 1 个Byte,即8位;而字符是占 2 个Byte,即 16 位。而且,需要注意的是,java 的字节是有符号类型,而字符是无符号类型。
字节流可以处理任何类型的数据,如图片、avi等,而字符流只能处理字符类型的数据。
Java 流操作的相关类或接口
- File – 文件类
- RandomAccessFile – 随机存储文件类
- InputStream – 字节输入流
- OutputStream – 字节输出流
- Reader – 字符输入流
- Writer – 字符输出流
Java流类图结构
今天我们先来学习 File
java.io.File
File 概念
File 是“文件”和“目录路径名”的抽象表示形式。
File 封装一个磁盘路径,例如 “d:/a/a.txt”、"d:/a/b/"等。可以是文件路径,也可以是目录路径,当然也可以封装不存在的路径。
创建对象
1、File file = new File(“d:/abc/a.txt”);
2、File file = new File(“d:/abc/”,“a.txt”);
File 的方法列表
boolean canExecute() 是否可执行
boolean canRead() 是否可读
boolean canWrite() 是否可写
int compareTo(File pathname) 比较两个抽象的路径名字典。
boolean createNewFile() 当且仅当具有该名称的文件尚不存在时,创建一个由该抽象路径名命名的新的空文件。
static File createTempFile(String prefix, String suffix) 在系统临时创建目录
static File createTempFile(String prefix, String suffix, File directory) 在指定的目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。
boolean delete() 删除文件或"空目录",能删除目录,但是里边有东西就不能删
void deleteOnExit() 请求在虚拟机终止时删除由此抽象路径名表示的文件或目录。
boolean equals(Object obj) 测试此抽象路径名与给定对象的相等性。
boolean exists() 表示的路径是否存在
File getAbsoluteFile() 返回此抽象路径名的绝对形式。
String getAbsolutePath() 返回完整路径
File getCanonicalFile() 返回此抽象路径名的规范形式。
String getCanonicalPath() 返回此抽象路径名的规范路径名字符串。
long getFreeSpace() 可用空间
String getName() 返回文件或目录的名
String getParent() 返回父目录的路径名字符串,如果此路径名未命名为父目录,则返回 null 。
File getParentFile() 返回此抽象路径名的父目录的抽象路径名,如果此路径名不指定父目录,则返回 null 。
String getPath() 将此抽象路径名转换为路径名字符串。
long getTotalSpace() 空间大小
long getUsableSpace() 通过此抽象路径名返回分区 named上此虚拟机可用的字节数。
int hashCode() 计算此抽象路径名的哈希码。
boolean isAbsolute() 测试这个抽象路径名是否是绝对的。
boolean isDirectory() 文件是否为目录
boolean isFile() 是否为普通文件
boolean isHidden() 是否隐藏文件
long lastModified() 返回此上次修改的时间,毫秒值
long length() 返回的文件的长度即文件字节量,对目录无效
String[] list() 返回String[],包含子文件,子目录名
String[] list(FilenameFilter filter) 返回一个字符串数组,命名由此抽象路径名表示的目录中满足指定过滤器的文件和目录。
File[] listFiles() 返回File[],包含子文件,子目录的File对象
File[] listFiles(FileFilter filter) 返回一个抽象路径名数组,表示由此抽象路径名表示的满足指定过滤器的目录中的文件和目录。
File[] listFiles(FilenameFilter filter) 返回一个抽象路径名数组,表示由此抽象路径名表示的满足指定过滤器的目录中的文件和目录。
static File[] listRoots() 列出可用的文件系统根。
boolean mkdir() 创建单层目录
boolean mkdirs() 创建多层目录,如果创建d:/aa/bb/cc/dd,这个方法会补全前面不存在的目录
boolean renameTo(File dest) 改名、移动
boolean setExecutable(boolean executable) 为此抽象路径名设置所有者的执行权限的便利方法。
boolean setExecutable(boolean executable, boolean ownerOnly) 设置该抽象路径名的所有者或每个人的执行权限。
boolean setLastModified(long time) 设置由此抽象路径名命名的文件或目录的最后修改时间。
boolean setReadable(boolean readable) 一种方便的方法来设置所有者对此抽象路径名的读取权限。
boolean setReadable(boolean readable, boolean ownerOnly) 设置此抽象路径名的所有者或每个人的读取权限。
boolean setReadOnly() 标记由此抽象路径名命名的文件或目录,以便只允许读取操作。
boolean setWritable(boolean writable) 一种方便的方法来设置所有者对此抽象路径名的写入权限。
boolean setWritable(boolean writable, boolean ownerOnly) 设置此抽象路径名的所有者或每个人的写入权限。
Path toPath() 返回从此抽象路径构造的一个java.nio.file.Path对象。
String toString() 返回此抽象路径名的路径名字符串。
URI toURI() 构造一个表示此抽象路径名的 file: URI。
URL toURL() 已过时。 此方法不会自动转义URL中非法的字符。 建议在新的代码转换的抽象路径到URL通过先转换成URI,经由toURI方法,然后经由转换URI为URL URI.toURL方法。
栗子1:文件或目录的属性练习
我需要用到 D 盘下 FileTest 文件夹中的 read_me.html
String path;
//这样写会报错,因为 \ 需要转义
//path = "D:\FileTest\read_me.html";
//这样写是正确的:
//path = "D:\\FileTest\\read_me.html";
//或者使用另一个方向的斜杠
path = "D:/FileTest/read_me.html";//找一个存在的文件路径
File f = new File(path);
System.out.println("可读:"+f.canRead());//true
System.out.println("可写:"+f.canWrite());//true
System.out.println("可执行:"+f.canExecute());//true
System.out.println("是否隐藏:"+f.isHidden());//false
System.out.println("是否存在:"+f.exists());//true
System.out.println("完整路径:"+f.getAbsolutePath());//D:\FileTest\read_me.html
System.out.println("文件名:"+f.getName());//read_me.html
System.out.println("父目录:"+f.getParent());//D:\FileTest
System.out.println("最后修改时间:"+f.lastModified());//1632982461050
System.out.println("字节量:"+f.length());//310
System.out.println("是否目录:"+f.isDirectory());//false
System.out.println("是否文件:"+f.isFile());//true
System.out.println("总空间:"+f.getTotalSpace());//127806730240
System.out.println("可用空间:"+f.getFreeSpace());//22729203712
大家可以尝试把 path 路径改为一个存在的目录路径,然后 改成一个不存在的路径,分别观察下上面程序的输出结果。
栗子2:文件或目录操作
public class Main {
public static void main(String[] args) throws IOException {
File f = new File("d:/abc/f1");
if (f.exists()) {
//文件存在,删除
boolean b = f.delete();
System.out.println("删除是否成功:" + b);
} else {
//文件不存在,创建
/*
*1、文件已经存在,会返回 false
*2、目录不存在,会出现异常
*/
boolean b = f.createNewFile();
System.out.println("创建是否成功:" + b);
}
}
}
因为要创建d:/abc/f1
,如果d:/abc
这个目录不存在会出现异常
因此在 d 盘下新建 “abc” 目录后再执行
继续看下面代码:
File f = new File("d:/abc/aa/bb/cc");
if (f.exists()) {
//文件存在,删除
boolean b = f.delete();
System.out.println("删除是否成功:" + b);
} else {
boolean b = f.mkdir();
System.out.println("创建是否成功:" + b);
}
输出结果
创建是否成功:false
因为路径是d:/abc/aa/bb/cc
,要创建 cc 目录,用mkdir()
必须保证 aa、bb、cc 存在才能创建成功。所以可以采用mkdirs()
方法,这个方法会补全缺失的目录。
再运行程序,会删除 cc 目录,因为路径表示的是 cc 目录,运行结果:
删除是否成功:true
再次创建 cc 目录,并在 cc 目录下创建 cc.txt,再次执行程序,会输出 删除是否成功:false
,因为 delete 能删除目录,但只能删除空目录
栗子3:创建临时目录
我们可以在 cmd 中查看系统临时目录路径
以下代码会在刚才的临时目录路径下创建临时文件
File f = File.createTempFile("abc", ".txt");
System.out.println(f.getAbsolutePath());
输出结果
C:\Users\00lix\AppData\Local\Temp\abc6930005239980148199.txt
创建完临时文件,可以不用删除,临时文件会被系统或者关键类的工具清理掉,不过最好可以手动删除一下
f.delete();
如果文件名只指定一个字母 “a”,
File f = File.createTempFile("a", ".txt");
System.out.println(f.getAbsolutePath());
会报错,前缀太短,因为这个方法对前缀有要求,至少3个字符
栗子4:文件列表方法练习
File dir = new File("d:/abc/");
String[] names = dir.list();
for (String s : names) {
System.out.println(s);
}
File[] files = dir.listFiles();
for (File f : files) {
System.out.println(f.getName() + "-" + f.length());
}
运行结果
list()
方法会返回一个字符数组,将制定路径下的文件或文件夹名字存储到 String 数组中。因为其返回的是一个 String 类型的数组,所以它也就只是一个名字而已。
listFiles()
及其重载方法则不同,它们返回的是 File 类型的对象,所以具有其全部的属性和方法
栗子5:求目录总大小
public class Main {
public static void main(String[] args) {
System.out.println("输入目录路径");
String s = new Scanner(System.in).nextLine();
File dir = new File(s);
if (!dir.isDirectory()) {
System.out.println("请输入正确的目录路径");
return;
}
System.out.println(dirLength(dir));
}
private static long dirLength(File file) {
/*
* 1、获得 dir 的目录列表赋值给 files
* 2、如果 files == null
* 3、return 0
* 4、定义累加变量 sum
* 5、遍历 files 数组,取出的 File 对象赋值给 f
* 6、如果 f 是文件
* 7、获得 f 大小,累加到 sum
* 8、如果 f 是目录
* 9、递归求 f 目录的大小,累加到 sum
* 10、返回 sum
*/
File[] files = file.listFiles();
if (files == null) {
return 0;
}
long sum = 0;
for (File f : files) {
if (f.isFile()) {
sum += f.length();
} else {
sum += dirLength(f);
}
}
return sum;
}
}
运行结果
栗子6:筛选后缀为.exe的文件
public class Main {
public static void main(String[] args) {
File dir = new File("c:/windows/");
String[] names = dir.list(new FilenameFilter() {
@Override
public boolean accept(File arg0, //arg0表示文件的当前目录
String arg1) {//arg1表示文件名)
//列出后缀为.exe的文件
//先全部转为小写就可以忽略大小写
return arg1.toLowerCase().endsWith(".exe");
}
});
for (String s : names) {
System.out.println(s);
}
}
}
运行结果:
栗子7:筛选大小大于1M的文件
File dir = new File("c:/windows/");
File[] files = dir.listFiles(new FileFilter() {
@Override
public boolean accept(File arg0) {
if (arg0.isDirectory()) {
return false;
}
return arg0.length() >= 1024 * 1024;
}
});
for (File f : files) {
System.out.println(f.getName() + "-" + f.length());
}
运行结果
栗子8:renamTo使用说明
File f1 = new File("d:/abc/f1");
File f2 = new File("d:/abc/fi-copy");
//异或是找不同,不同返回true,相同返回false
if (!(f1.exists() ^ f2.exists())) {
System.out.println("两个文件不能同时存在," +
"也不能同时不存在," +
"必须存在其中一个");
return;
}
//如果改名成功
if (f1.exists()) {
boolean b = f1.renameTo(f2);
System.out.println("改名成功:" + b);
} else {
boolean b = f2.renameTo(f1);
System.out.println("改名成功:" + b);
}
输出结果