• 【javaEE】——文件和IO操作05


    目录

    一、文件的认识

    1.1 Java 中操作文件

    二、文件的读写——数据流

    2.1 字节流的读写操作

    2.2 字符流的读写操作(Reader、Writer)

    三、编程练习

    3.1 删除文件

    3.2 普通文件的复制

    3.3 扫描目录


    一、文件的认识

    系统中:“一切皆文件”。普通的文件是保存在硬盘(持久化存储的I/O设备)上的文件

    元信息:文件的相 关属性(文件名、文件类型、文件大小等)

    文件分类:文本文件(存储字符)、二进制文件(字节)

    文件(剪切粘贴):高效,只需修改文件属性中的地址即可
    文件(复制粘贴):低效,先读文件内容,再拷贝一份写入磁盘,开销大 

    1.1 Java 中操作文件

    Java 中通过 java.io.File 类来对一个文件(包括目录)进行抽象的描述。

     File file = new File("d:/test.txt");  //给定地址下 创建一个文件

    注意!!!有 File 对象,并不代表真实存在该文件。

    • 1.指定路径时,路径分隔使用正斜杠/---->"d:/test.test";
    • 2.若使用反斜杠\,则需转义:\\----->"d:\\test.test"
    1. import java.io.File;
    2. import java.io.IOException;
    3. public class fileDemo {
    4. public static void main(String[] args) throws IOException {
    5. File file = new File("d:/test.txt"); //给定地址下 创建一个文件
    6. System.out.println(file.getName()); //获取文件名
    7. System.out.println(file.getParent()); //获取父目录
    8. System.out.println(file.getAbsoluteFile()); //获取绝对路径
    9. System.out.println(file.getCanonicalFile()); //相对路径
    10. System.out.println(file.exists()); //文件是否存在
    11. System.out.println(file.isFile()); //是否是一个普通文件
    12. System.out.println(file.isDirectory()); //是否是目录
    13. File file1 = new File("./aaa"); // 创建目录
    14. System.out.println(Arrays.toString(file1.list())); //列出目录下的文件
    15. System.out.println(Arrays.toString(file.listFiles()));
    16. }
    17. }

    二、文件的读写——数据流

    • 字节流:8位  ,针对二进制文件(读:InputStream;写:OutputStream)
    • 字符流:2字节,16比特位,针对文本文件(读:Reader;写:Writer)。

    抽象类可针对普通文件、特殊文件(网卡、socket)进行读写;实际使用中都是使用这四个类的子类(FileInputStream、FileOutputStream、FileReader、FileWriter),子类只可对普通文件进行读写

    abstract 抽象类,不能实例化
    抽象方法(不需要实现)必须在抽象类里,使用时需创建子类,来重写这个方法

    “流”stream对象

    2.1 字节流的读写操作

    (1)读文件

    1. public static void main0(String[] args) {
    2. InputStream inputStream = null;
    3. try {
    4. inputStream = new FileInputStream("d:/test.txt");
    5. while (true) {
    6. int b = inputStream.read(); //一次读一个字节(一个字节的范围:-128,127)
    7. if (b == -1) { //读到了文件末尾
    8. break;
    9. }
    10. System.out.println(b); //若为字母则输出字母对应的ASCII值
    11. }
    12. } catch (IOException e) { //读操作可能触发的异常
    13. e.printStackTrace();
    14. } finally {
    15. try { //读完及时关闭文件,释放资源
    16. inputStream.close();
    17. } catch (IOException e) {
    18. e.printStackTrace();
    19. }
    20. }
    21. }
    22. //=================代码改进:读一个字节===================//
    23. public static void main(String[] args) { // 此代码try会自动调用close
    24. try (InputStream inputStream = new FileInputStream("d:/test.txt")) {
    25. while (true) {
    26. int b = inputStream.read();
    27. if (b == -1) {
    28. break;
    29. }
    30. System.out.println(b);
    31. }
    32. }catch (IOException e) {
    33. e.printStackTrace();
    34. }
    35. }
    36. //=================代码改进:读取多个字节===================//
    37. public static void main(String[] args) { // 此代码try会自动调用close
    38. try (InputStream inputStream = new FileInputStream("d:/test.txt")) {
    39. while (true) {
    40. byte[] buffer = new byte[1024]; //把读取的数据放到buffer数组中,以此来指代返回结果
    41. int len = inputStream.read(buffer); //读取多个字节
    42. if (len == -1) {
    43. break;
    44. }
    45. for (int i = 0; i < len; i++) {
    46. System.out.println(buffer[i]);
    47. }
    48. }
    49. }catch (IOException e) {
    50. e.printStackTrace();
    51. }
    52. }

    (2)写文件:

    每次写文件都会清空原有文件,从起始位置往后写。OutputStream 同样只是一个抽象类,要使用还需要具体的实现类。所以使用 FileOutputStream

     I / O  速度很慢,所以,大多的 OutputStream 为了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的一个指定区域buffer里,直到该区域满了或者其他指定条件时才真正将数据写入设备中,这个区域一般称为缓冲区。但造成一个结果,就是写的数据,很可能会遗留一部分在缓冲区中。需要在最后或者合适的位置,调用 flush(刷新)操作,将数据刷到设备中

    1. //=========================代码改进:写文件=====================//
    2. public static void main(String[] args) { // 此代码try会自动调用close
    3. try (OutputStream outputStream = new FileOutputStream("d:/test.txt")) {
    4. while (true) {
    5. byte[] buffer = new byte[1024]; //把读取的数据放到buffer数组中,以此来指代返回结果
    6. outputStream.write(buffer); //读取多个字节
    7. }
    8. }catch (IOException e) {
    9. e.printStackTrace();
    10. }
    11. }

    2.2 字符流的读写操作(Reader、Writer)

     读操作:

    1. public class Demo1 {
    2. public static void main(String[] args) {
    3. try(Reader reader =new FileReader("d:/test.txt")) {
    4. while (true) {
    5. char[] chars = new char[1024];
    6. int len = reader.read();
    7. if (len == -1) {
    8. break;
    9. }
    10. // for (int i = 0; i < len; i++) {
    11. // System.out.println(chars[i]);
    12. // }
    13. String str = new String(chars,0,len);
    14. System.out.println(str);
    15. }
    16. }catch(IOException e) {
    17. e.printStackTrace();
    18. }
    19. }
    20. }

    写操作:

    1. public static void main(String[] args) {
    2. try(Writer writer = new FileWriter("d:/test.txt")) {
    3. writer.write("asdf");
    4. }catch (IOException e) {
    5. e.printStackTrace();
    6. }
    7. }

    三、编程练习

    3.1 删除文件

    扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要删除该文件

    1. import java.io.File;
    2. import java.io.IOException;
    3. import java.util.Scanner;
    4. public class testDemo {
    5. public static void main(String[] args) {
    6. //1.输入要扫描的目录,以及删除的文件名
    7. Scanner in = new Scanner(System.in);
    8. System.out.println("请输入扫描路径");
    9. String scanRootPath = in.nextLine();
    10. System.out.println("请输入文件名");
    11. String toDelName = in.nextLine();
    12. File rootDir = new File(scanRootPath); //创建一个目录
    13. if (!rootDir.isDirectory()) { //判断是不是文件夹,若不是文件夹,退出
    14. System.out.println("输入的扫描路径有误,直接退出");
    15. return;
    16. }
    17. // 二叉树的遍历(先序,中序,后序,层序)
    18. scanDir(rootDir,toDelName); // 遍历指定目录的所有文件和子目录,找到需要删除的文件(可通过遍历实现递归操作并删除)
    19. }
    20. private static void scanDir(File rootDir, String toDelName) {
    21. File[] files = rootDir.listFiles(); //先列出rootDir中都有的内容
    22. if (files == null) {
    23. return;
    24. }
    25. for (File f : files) {
    26. if (f.isFile()) { //普通文件的情况
    27. if (f.getName().contains(toDelName)) {
    28. deleteFile(f); //删除文件
    29. }
    30. } else if (f.isDirectory()) { //目录进行递归
    31. scanDir(f,toDelName); //递归操作,继续遍历
    32. }
    33. }
    34. }
    35. private static void deleteFile(File f) {
    36. try {
    37. System.out.println(f.getCanonicalPath() + "确认要删除吗?(Y/N)");
    38. Scanner in = new Scanner(System.in);
    39. String chioce = in.next();
    40. if (chioce.equals("Y") || chioce.equals("y")) {
    41. f.delete(); //删除文件
    42. System.out.println("文件删除成功");
    43. }else {
    44. System.out.println("文件取消删除");
    45. }
    46. } catch (IOException e) {
    47. e.printStackTrace();
    48. }
    49. }
    50. }

    3.2 普通文件的复制

    1. import java.io.*;
    2. import java.util.Scanner;
    3. public class copyDome {
    4. public static void main(String[] args) {
    5. Scanner in = new Scanner(System.in);
    6. System.out.println("请输入源文件地址");
    7. String srcPath = in.nextLine();
    8. System.out.println("请输入目标文件地址");
    9. String newPath = in.nextLine();
    10. File srcFile = new File(srcPath); //创建源文件对象
    11. if (!srcFile.isFile()) {
    12. System.out.println("输入有误,不是一个文件");
    13. return;
    14. }
    15. //进行文件的读取和写入(拷贝):把inputStream读取到的内容复制(写入)到outputStream
    16. try (InputStream inputStream = new FileInputStream("srcPath")) {
    17. try (OutputStream outputStream = new FileOutputStream("newPath")) {
    18. byte[] buffer = new byte[1024]; //创建一个缓冲区用于存放数据
    19. while (true) {
    20. int len = inputStream.read(buffer); //从buffer读取所有数据
    21. if (len == -1) { // -1 表明数据读取完毕
    22. break;
    23. }
    24. outputStream.write(buffer,0,len);
    25. }
    26. }
    27. } catch (IOException e) {
    28. e.printStackTrace();
    29. }
    30. }
    31. }

    3.3 扫描目录

    扫描指定目录,并找到名称或者内容中包含指定字符的所有普通文件(不包含目录)

    注意:我们现在的方案性能较差,所以尽量不要在太复杂的目录下或者大文件下实验

    1. import java.io.File;
    2. import java.io.FileReader;
    3. import java.io.IOException;
    4. import java.io.Reader;
    5. import java.util.Scanner;
    6. public class scanDemo {
    7. public static void main(String[] args) throws IOException {
    8. Scanner in = new Scanner(System.in);
    9. System.out.println("输入要扫描的路径:");
    10. String rootDirPath = in.nextLine();
    11. System.out.println("输入要查找的关键词:");
    12. String words = in.nextLine();
    13. File rootDir = new File(rootDirPath); //创建目录下的文件夹对象
    14. if (!rootDir.isDirectory()) {
    15. System.out.println("输入的路径不正确");
    16. return; //退出
    17. }
    18. scanDir(rootDir,words); //遍历目录,查找关键字对应的文件
    19. }
    20. private static void scanDir(File rootDir,String words) throws IOException {
    21. File[] files = rootDir.listFiles(); //列举出rootDir文件夹下对应的所有文件
    22. if (files == null) {
    23. return;
    24. }
    25. for (File f: files) { //遍历所有文件
    26. if (f.isFile()) {
    27. if (containsWords(f,words)) {
    28. System.out.println(f.getCanonicalPath()); //输出对应的路径
    29. }
    30. } else if (f.isDirectory()) {
    31. scanDir(f,words);
    32. }
    33. }
    34. }
    35. private static boolean containsWords(File f,String words) {
    36. StringBuilder stringBuilder = new StringBuilder();
    37. try(Reader reader = new FileReader(f)) { //字符流读取数据
    38. char[] chars = new char[1024];
    39. while (true) {
    40. int len = reader.read(chars);
    41. if (len == -1) {
    42. break;
    43. }
    44. stringBuilder.append(chars,0,len); //把读取到的数据放到stringBuilder
    45. }
    46. } catch (IOException e) {
    47. e.printStackTrace();
    48. }
    49. return stringBuilder.indexOf(words) != -1; //indexOf返回字串的下标
    50. }
    51. }

  • 相关阅读:
    STP---生成树协议
    自主设计,模拟实现 RabbitMQ - 实现发送方消息确认机制
    SpringBoot项目--电脑商城【显示商品详情功能】
    [附源码]计算机毕业设计JAVAssm实验教学资源管理系统
    这个IfxCpu_Trap_busError函数是干嘛的
    利用各种命令取网卡ip地址
    “Cloud“(云)
    中项2022
    何为智能指针以及QT中的智能指针
    【数独问题】递归+回溯算法求解数独问题
  • 原文地址:https://blog.csdn.net/qq_45864756/article/details/127753616