Day23
一、File
知识点:File - 文件类
File,是文件和目录路径名的抽象表示
File只关注文件本身的信息,而不能操作文件里面的内容File类 – 表示文件或文件夹,不能对文件里的数据进行操作
对文件里的数据进行操作的是:IO流需求1:通过程序,获取已知文件的以下信息
public static void main(String[] args) { //创建file对象 File file = new File("C:\\Users\\hhy.txt"); System.out.println("获取文件名:" + file.getName()); System.out.println("获取路径:" + file.getAbsolutePath()); System.out.println("获取是否可读:" + file.canRead()); System.out.println("获取是否可写:" + file.canWrite()); System.out.println("获取是否隐藏:" + file.isHidden()); System.out.println("获取文件大小(字节):" + file.length()); SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); String datetime = sdf.format(file.lastModified()); System.out.println("获取文件最后修改时间:" + datetime); }
知识点:相对路径 和 绝对路径
绝对路径:指定盘符的路径
相对路径:相对于项目下的路径public static void main(String[] args) { File file = new File("hhy.txt"); //hhy.txt System.out.println("获取相对路径:" + file.getPath()); //D:\2402workspace\Day23\hhy.txt System.out.println("获取绝对路径:" + file.getAbsolutePath()); }
需求2:通过程序,判断指定路径的文件是否存在,如果不存在,则创建该文件
下面按各种情况来解决该问题1)目录已存在的情况
public static void main(String[] args) throws IOException { File file = new File("file01//hhy.txt"); if(!file.exists()){//判断文件是否存在 //创建文件 file.createNewFile(); } }
2)有一个层级的目录不存在的情况
public static void main(String[] args) throws IOException { File file = new File("file01//hhy.txt"); //获取父路径的file对象 -- file01 File parentFile = file.getParentFile(); if(!parentFile.exists()){//判断目录路径是否存在 //创建一层目录 parentFile.mkdir(); } if(!file.exists()){//判断文件是否存在 //创建文件 file.createNewFile(); } }
3)有多个层级的目录不存在的情况
public static void main(String[] args) throws IOException { File file = new File("file01//file02//file03//hhy.txt"); //获取父路径的file对象 -- file01//file02//file03 File parentFile = file.getParentFile(); if(!parentFile.exists()){//判断目录路径是否存在 //创建多层目录 parentFile.mkdirs(); } if(!file.exists()){//判断文件是否存在 //创建文件 file.createNewFile(); } }
需求3:输出指定目录下的所有文件信息(只考虑当前目录,不考虑子目录)
public static void main(String[] args) { File file = new File("D:\\2023"); //获取当前路径下所有的文件名 String[] list = file.list(); for (String str : list) { System.out.println(str); } //获取当前路径下所有的file对象 File[] listFiles = file.listFiles(); for (File f : listFiles) { System.out.println(f.getName() + " -- " + f.canRead() + " -- " + f.canWrite()); } }
1)要求只输出文件后缀名为txt的文件
public static void main(String[] args) { File file = new File("D:\\2023"); //获取当前路径下所有的文件名 // String[] list = file.list(); // for (String str : list) { // if(str.endsWith(".txt")){ // System.out.println(str); // } // } //获取当前路径下所有的file对象 File[] listFiles = file.listFiles(); for (File f : listFiles) { String name = f.getName(); if(name.endsWith(".txt") && f.isFile()){ System.out.println(name); } } }
2)根据API的过滤器来完成该功能
public static void main(String[] args) { File file = new File("D:\\2023"); File[] listFiles = file.listFiles(new FilenameFilter() { //底层逻辑:遍历当前目录所有的file对象,返回true就添加到listFiles数组中,返回false就不管 @Override public boolean accept(File dir, String name) { //D:\\2023 + \\ + 文件名 File f = new File(dir, name); String n = f.getName(); if(n.endsWith(".txt") && f.isFile()){ return true; } return false; } }); for (File f : listFiles) { System.out.println(f.getName()); } }
3)需求继续跟进,列出当前目录及子目录中符合该条件的文件信息(递归)
public static void main(String[] args) { File file = new File("D:\\2023"); method(file, ".txt"); } public static void method(File file,String suffix){ File[] listFiles = file.listFiles(); for (File f : listFiles) { if(f.isDirectory()){//文件夹 method(f, suffix); }else if(f.isFile()){//文件 String name = f.getName(); if(name.endsWith(suffix)){ System.out.println(name + " -- " + f.getAbsolutePath()); } } } }
二、IO流
概念
I ---- in – 输入(将外界的数据传入到程序中)
O – out – 输出(将程序中的数据传出到外界)
流 – 一点点的传输
注意:站在程序的角度理解输入输出
分类
按照方向分:输入流、输出流
按照单位分:字节流、字符流
按照功能分:节点流/基础流、处理流
注意:处理流往往是包含着节点流,让流的功能更加强大 – new 处理流(new 基础流);
存储单位进制
1024byte = 1Kb
1024Kb = 1Mb
1024Mb = 1Gb
1024G = 1Tb
1024Tb = 1Pb
注意:每年10月24日是程序员节
学习路线及经验
- 按照流的发展历史学习
- 关注继承关系
- 举一反三
字节流
abstract class InputStream – 字节输入流(字节流的基类)
abstract class OutputStream – 字节输出流(字节流的基类)
class FileInputStream extends InputStream – 文件字节输入流
class FileOutputStream extends OutputStream – 文件字节输出流
class FilterInputStream extends InputStream -过滤器字节输入流
class FilterOutputStream extends OutputStream - 过滤器字节输出流
class BufferedInputStream extends FilterInputStream - 带有缓冲区的字节输入流(默认缓冲区大小 8192 字节)
class BufferedOutPutStream extends FilterOutputStream - 带有缓冲区的字节输出流(默认缓冲区大小 8192 字节)
[!warning]
所有的输出流,当文件不存在时都会先创建该文件,再写入数据
所有的输入流,当文件不存在时都会报错-FileNotFoundException
[!note]
当不考虑效率时,使用FileOutputStream、 FileInputStream
当考虑效率时,使用BufferedInputStream 、 BufferedOutPutStream
//利用文件字节输入流向文件读取数据
public static void main(String[] args){
//1.创建流
FileInputStream fis = null;
try{
//所有的输入流,当文件不存在时报FileNotFoundException
fis = new FileInputStream("qqq/123.txt");
//2.读取数据
byte[] bs = new byte[1024];
int len;
//read(bs):读取bs数组长度的数据并把数据存入数组中,返回读取到的有效字节数。
//当读取到文件结尾时,返回的值为-1
while((len = fis.read(bs)) != -1){
System.out.println(new String(bs, 0, len));
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally{
if(fis != null){
try{
//3.关闭资源
fis.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
//利用文件字节输出流向文件写入数据
public static void main(String[] args) {
//利用文件字节输出流向文件写入数据
FileOutputStream fos = null;
//经验:操作文件字节输出流一般不使用throws处理异常
try {
//1.创建流对象
fos = new FileOutputStream("qqq/1234.txt",true);//true代表是追加模式
//2.写入数据
fos.write("1234qwer".getBytes());
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
//经验:try的部分代码越少越好
if (fos != null) {
try {
//3.关闭资源
fos.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
拷贝文件(文件上传下载)
public static void main(String[] args) {
//在try括号中的代码,try完成后都会自动关闭,省去了fis,close()和fos.close()的步骤
try(FileInputStream fis = new FileInputStream("qqq/123.txt");FileOutputStream fos = new FileOutputStream("123_copy.txt");) {
byte[] bs = new byte[1024];
int len;
while((len = fis.read(bs)) != -1) {
fos.write(bs, 0, len);
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
带缓冲区
知识点:利用 带缓冲区的字节输出流 向文件写入数据
1)不处理异常的方式 2)文件存在的情况 3)在末尾追加 经验:考虑基础流的构造方法 4)文件不存在的情况 经验:所有的输出流,当文件不存在时都会先创建该文件,再写入数据 5)处理异常的方式
public static void main(String[] args) throws IOException{ //1.创建流对象 //BufferedOutputStream bos = new BufferedOutputStream(new FileOutStream("hhy.txt")); //1.创建流对象 + 末尾追加 //BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("hhy.txt",true)); //1.创建流对象 + 自定义长度 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("hhy.txt"),2048); //2.写入数据 bos.write("123abc".getBytes()); bos.write("123abc".getBytes()); //3.关闭资源 bos.close(); }
知识点:利用 带缓冲区的字节输入流 读取文件里的数据
1)不处理异常的方式 2)文件存在的情况 3)文件不存在的情况 经验: 所有的输出流,当文件不存在时都会先创建该文件,再写入数据 所有的输入流,当文件不存在时都会报错 - FileNotFoundException 4)处理异常的方式
public static void main(String[] args) throws IOException { //1.创建流对象 //BufferedInputStream fis = new BufferedInputStream(new FileInputStream("hhy.txt")); //1.创建流对象 + 自定义缓冲区大小 BufferedInputStream fis = new BufferedInputStream(new FileInputStream("hhy.txt"),2048); //2.读取数据 byte[] bs = new byte[1024]; int len; while((len = fis.read(bs)!=-1){ System.out.println(new String(bs,0,len)); } //3.关闭资源 fis.close(); }