文件 & File类的使用
1、文件的概念
文件可以分为文本文件 二进制文件
2、IO流的概念 流是有顺序、有起点和终点的集合,是对数据传输的总称。流的本质就是用来对数据进行操作 IO是我们实现的目的,实现这个目的需要利用的机制就是流机制 (从起点 读取 写入 终点)
3、流的分类
- 1)按照流向 输入流 和 输出流 输入流指的是 从键盘 文件 鼠标读取到程序内存的过程 输出流指的是 从程序内存写入到磁盘 打印机 文件的过程
- 2)按照传输类型 字节流 和 字符流 字节流指的是传输的数据是以字节为单位的 字符流指的是传输的数据是以字符为单位的
- 3)按照角色 节点流和处理流(装饰器设计模式) 节点流指的是程序直接连接到实际的数据源 处理流指的是,对节点流做了一层封装,通过封装后的流来实现数据的读取和写入功能
4.常用方法
- boolean exist 判断当前路径是否存在
- boolean isFile 当前路径对应是一个文件
- boolean isDirectory 当前路径对应是一个目录
- boolean createNewFile 在当前文件不存在的情况下,创建新文件
- boolean isHidden 判断是否是隐藏文件
- boolean delete 删除文件
- file.mkdir 创建目录
- file.getName 获取文件名
- file.getAbsolutePath 获取文件绝对路径,windows不带盘符的路径表示相对路径; linux 不带/ .表示当前目录 ..表示上一级目录; 绝对路径 完整的路径名称
- file.listFiles 获取当前目录下的所有文件 返回类型为File[]
- file.list 获取当前目录下的所有文件 返回类型为String[]
测试:
- 创建两个文件对象,分别使用相对路径和绝对路径
File file1 = new File("./a.txt"); //创建了一个文件对象,对应不会创建这样一个物理文件
File file2 = new File("/Users/admin/desk/test/test.txt");
- 检查文件是否存在,不存在则创建文件
if(!file1.exists()){
try {
file1.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
if(!file2.exists()){
try {
file2.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
- 创建单级目录
File file3 = new File("./aaa");
if(!file3.exists()){
file3.mkdir();
}
- 创建多级目录
File file4 = new File("./bbb/ccc");
if(!file4.exists()){
file4.mkdirs();
}
- 删除文件 目录(该目录下的所有文件都删除)
file1.delete();
file2.delete();
file3.delete(); //只能删除单级空目录
file4.delete(); //无法删除多级目录
java中没有删除多级目录的函数,但是可以通过递归进行删除
//递归删除多级目录
public static void delete(File file){
if(file == null || !file.exists()){
return;
}
if(file.isFile()){
file.delete();
}else{
//递归删除多级目录
deleteDir(file);
}
}
public static void deleteDir(File file){
//递归的终止条件
File[] files = file.listFiles();
if(files == null){
//表示当前目录是一个空目录
//满足终止条件的返回结果
return;
}
//相同逻辑
//继续遍历该文件对象的集合
for(File f: files){
if(f.isFile()){
//该文件对象是一个文件 直接删文件
f.delete();
}else{
deleteDir(f);
}
}
file.delete(); //删除当前空的目录
}
- 获取文件名、文件大小、文件的绝对路径、父路径
File file5 = new File( "./test.txt");
if(!file5.exists()){
try {
file5.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println(file5.getName());
System.out.println(file5.length());
System.out.println(file5.getAbsolutePath());
System.out.println(file5.getParentFile());
- 文件和目录的判断
if(file5.isFile()){
System.out.println("fild5是一个file");
}else{
System.out.println("file5是一个directory");
}
- 获取某一个目录下的所有文件
//listFiles->返回文件对象的集合 list->文件pathName的集合
File file = new File("D:\\Compressed\\study2021\\");
File[] files = file.listFiles();
System.out.println(Arrays.toString(files));
String[] strs = file.list();
for(String s:strs){
System.out.println(s);
}
- 从键盘上输入一个路径,打印出该路径下所有.java文件
public static void printJavaFile(File dir){
if(dir == null || !dir.exists()){
return;
}
File[] subFiles = dir.listFiles();
if(subFiles == null){
//表示dir是一个空目录
return;
}
//遍历文件对象的集合,要么该文件对象对应的就是一个文件,
//要么对应的还是一个目录
for(File f: subFiles){
if(f.isFile() && f.getName().endsWith(".java")){
System.out.println(f.getName());
}else{
printJavaFile(f);
}
}
}
字节流
1.概念基础
字节流有输入流InputStream & 输出流OutputStream两大类
输入流:读取数据
输出流:写入数据
构造函数:
public FileInputStream(String name)
public FileInputStream(File file)
成员方法 :
public int read() ,按字节进行读取
public int read(byte b[]),将字节读取到byte数组中
public int read(byte b[], int off, int len),将字节读取到byte数组中,读取的其实位置为off,长度为len
知识点:
1)FileInputStream用于读取文件数据,可以在构造函数中传入文件对象,也可以传入文件名, 但是有可能抛出FileNotFoundException
2)read方法使用时
a.存在3个重载方法,read每次读取一个字节,read(byte[] b)每次读取b.length个字节, read(byte b[], int off, int len)每次读取len个字节
b.有可能在读取过程中抛出异常,比如文件某部分数据损坏
c.如果读取读到-1就表示已经读到了文件末尾
2.FileInputStream
给定a.txt,读取a.txt中所有数据并输出
两种方式实现,一种方式是采用while循环,每次通过read()读取一个字节,判断当前读到的字节是否为-1,如果为-1就说明读到文件的末尾,终止循环,否则就将读到的字节数据进行打印输出。
另一种方式是将字节读到byte数组中,进行打印输出。
public static void main(String[] args) {
try {
FileInputStream fs = new FileInputStream("test.txt");
int temp;
byte[] bytes = new byte[256];
try {
while((temp = fs.read()) != -1){
System.out.println(temp);
}
// temp = fs.read(bytes);
// System.out.println(temp);
// System.out.println(Arrays.toString(bytes));
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
PS:read()读取到返回的是一个int,而不是byte。这样做的原因是,假设现在读到为1111 1111 , 读到这的时候对应-1的补码,计算机就会认为上读到-1了,终止读操作,但实际没有读完,因此转为int 0000 0000 0000 0000 0000 0000 1111 1111,这样就能避免这个现象。
3.FileOutputStream
public static void main(String[] args) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream("b.txt");//如果不存在 输出流对象会自动创建该文件
byte[] bytes = {100, 101, 102, 103};
fos.write(105);
fos.write(bytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fos.close();//关闭流对象
} catch (IOException e) {
e.printStackTrace();
}
}