> 文档中心 > 给你朋友看看文件的别样操作

给你朋友看看文件的别样操作

目录

摘要

1.文件的概述

1.1文本文件

1.2二进制文件

 1.3目录结构

 2.Java操作文件

2.1 file的构造

 2.2判断文件是否存在

2.3文件的创建

 2.4文件的删除

 2.5目录的创建

3.文件的读取

4.写文件

4.1按照字符来读写

 4.2按照字符来写

 5.文件的查找并删除

 6.文件的复制

 7.扫描指定目录


摘要

通过Java对文件进行读、写、删、复制等操作。

Java 中通过 java.io.File 类来对一个文件(包括目录)进行抽象的描述。注意,有 File 对象,并不 代表真实存在该文件

1.文件的概述

我们通常说的文件一般是指存储在硬盘上的普通文件,形如 .txt .jpg .mp4 .rar 等这些文件都是普通文件,都在硬盘上存储着。

在计算机中,文件可能是一个广义的概念,就不只是包含普通文件,还包含文件夹等。

1.1文本文件

文本文件里面存储的是字符,本质上也是存储字节的。我们将一个文件用记事本打开,打开显示的不是乱码就是文本文件。如 .txt .c .java  .sql  等都属于文文文件。如下所示

1.2二进制文件

二进制文件里面存储的是字节。使用记事本打开之后是乱码,如下图所示。如 .doc   .ppt   .exe  .jpg   .png   .zip   等文件都是二进制文件。

 1.3目录结构

计算机里面,文件是通过“文件系统”模块来负责的,使用的是N叉树结构。

如果是一个普通文件,则是树的叶子节点。

如果是一个目录文件,目录中就可以包含子树,这个目录就是非叶子节点,这个树每个节点上的子树都可以有N个。

这就是一个N叉树

 在操作系统中,通过“路径”这样的概念来描述一个具体文件/目录的位置

1.绝对路径:以盘符开头的,如   

C:\Intel\Logs\DXP.exe

C:\Program Files\Google\Chrome\Application

2.相对路径 以 .  或者 .. 开头的。其中 . 表示当前路径。 ..表示当前路径的父目录。

相对路径就是从基准目录出发,按照一个路径找到的对应文件。

例如以C:\Intel\Logs为基准目录,找到 DXP.exe 。则  ./DXP.exe 中的 . 就是基准目录

还是以C:\Intel\Logs 为基准目录,找到 ddz.zip 。则 ../ddz.zip 中的 .. 就表示基准目录的上一级路径C:\Intel

 2.Java操作文件

文件系统相关的操作是指通过“文件资源管理器” 能够完成一些功能,如:列出目录中有哪些文件、创建文件、创建目录、删除文件、重命名文件等。

在Java中提供一个File 类,通过这个类来完成上诉操作,File 的构造方法能够传入一个路径,来指定一个文件。

2.1 file的构造

import java.io.File;import java.io.IOException;//file 的构造public class Test1 {    public static void main(String[] args) throws IOException { File f = new File("d:/test.txt"); System.out.println(f.getParent());//获取到文件的父目录 System.out.println(f.getName());//获取到文件名 System.out.println(f.getPath());//获取到文件路径(构造file 的时候的指定路径) System.out.println(f.getAbsolutePath());//获取绝对路径 System.out.println(f.getCanonicalFile());//获取绝对路径 System.out.println("------------------"); File f2 = new File("./test.txt"); System.out.println(f2.getParent());//获取到文件的父目录 System.out.println(f2.getName());//获取到文件名 System.out.println(f2.getPath());//获取到文件路径(构造file 的时候的指定路径) System.out.println(f2.getAbsolutePath());//获取绝对路径 System.out.println(f2.getCanonicalFile());//获取绝对路径    }}

 2.2判断文件是否存在

在这里,我并没有创建test.txt文件,所以结果都是false

import java.io.File;public class Test2 {    public static void main(String[] args) { File f = new File("d/test.txt"); System.out.println(f.exists());//判断 File 对象描述的文件是否真实存在 System.out.println(f.isDirectory());//判断 File 对象代表的文件是否是一个目录 System.out.println(f.isFile());//判断 File 对象代表的文件是否是一个普通文件    }}

 

2.3文件的创建

通过 createNewFile() 方法进行创建

import java.io.File;import java.io.IOException;public class Test3 {    public static void main(String[] args) throws IOException { File f = new File("./test.txt"); System.out.println(f.exists());//判断文件是否存在,false System.out.println("创建文件"); f.createNewFile(); System.out.println("创建结束"); System.out.println(f.exists());//判断文件是否存在,true    }}

 运行

 创建成功

 2.4文件的删除

import java.io.File;public class Test4 {    public static void main(String[] args) { File f = new File("./test.txt"); System.out.println(f.exists());//判断文件是否存在,true f.delete(); if(!f.exists()) {     System.out.println("删除成功"); }    }}

 刚开始我们是已经创建好test.txt文件的,所以是true ,然后我们再删除,经过判断输出“删除成功”

 2.5目录的创建

import java.io.File;public class Test5 {    public static void main(String[] args) { File f = new File("./abc"); f.mkdir();//创建abc目录 System.out.println(f.isDirectory());    }}

将目录的名字更改

import java.io.File;public class Test6 {    public static void main(String[] args) { File f = new File("./abc"); File f2 = new File("./aaa"); f.renameTo(f2);    }}

3.文件的读取

 用到的是 InputStream 。Stream是流对象,针对文件内容的读写,Java标准库提供了一组类,按照文件的内容,分为两个系列

1.字节流对象:针对二进制文件,以字节为单位进行读写,读InoutStream, 写 OutoutStream

2.字符流对象:针对文本文件,以字符为单位来读写,读Reader, 写Writer

 以上写的都是抽象类,是以 File....开头类的子类

import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;public class Test7 {    public static void main(String[] args)  { //构造方法需要指定打开文件的路径 //可以是绝对路径或者相对路径,还可以是file对象 InputStream inputStream = null; try {     //1.创建对象,同时也在打开文件     inputStream = new FileInputStream("./test.txt");     //2.尝试一个一个字节读,读完整个文件     while (true) {  int b = inputStream.read();  if (b == -1) {      //读到文件末尾      break;  }  System.out.println(b);     } } catch (IOException e) {     e.printStackTrace(); }finally {     //3.读完之后关闭文件,释放资源     try {  inputStream.close();     } catch (IOException e) {  e.printStackTrace();     } }    }}

 可以将上述代码优化

try (InputStream inputStream = new FileInputStream("test.txt")) {   //一次读取若干个   byte[] buffer = new byte[1024];   int len;   while (true) { len = inputStream.read();if (len == -1) {    //如果是 -1 ,则读取完毕    break;}for (int i = 0; i < len; i++) {    System.out.println(buffer[i]);}   }      }catch (IOException e) {   e.printStackTrace();      }

4.写文件

利用字节流对文件进行写

import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;public class Test8 {    public static void main(String[] args) { //使用字节流,写文件 try (OutputStream outputStream = new FileOutputStream("./test.txt")) {     outputStream.write(98);     outputStream.write(99);     outputStream.write(100); }catch (IOException e) {     e.printStackTrace(); }    }}

 在执行程序之前,我们先将test.txt 文件内的内容清空,然后执行代码进行写文件

4.1按照字符来读写

import java.io.FileReader;import java.io.IOException;import java.io.Reader;//按照字符来读写public class Test9 {    public static void main(String[] args) { try (Reader reader = new FileReader("./test.txt")) {     //按照字符来读     while (true) {  char[] buffer = new char[1024];  int len = reader.read(buffer);  if (len == -1) {      break;  }  //写  /*  for (int i = 0; i < len; i++) {      System.out.println(buffer[i]);  }   */  //如果传入的数组是 byte 数组,因使用 utf-8 字符集,避免乱码  String s = new String(buffer,0,len);  System.out.println(s);     } }catch (IOException e) {     e.printStackTrace(); }    }}

 

 4.2按照字符来写

import java.io.FileWriter;import java.io.IOException;import java.io.Writer;//按照字符来写public class Test10 {    public static void main(String[] args) { try (Writer writer = new FileWriter("./test.txt")) {     writer.write("Fly Upward"); }catch (IOException e) {     e.printStackTrace(); }    }}

 

 5.文件的查找并删除

import java.io.File;import java.io.IOException;import java.util.Scanner;//实现查找文件并删除public class Test11 {    public static void main(String[] args) { //1.先输入要扫描的目录,以及要删除的文件名 Scanner scanner = new Scanner(System.in); System.out.println("请输入要扫描的路径"); String rootDirPath = scanner.next(); System.out.println("请输入要删除的文件名:"); String toDeleteName = scanner.next(); File rootDir = new File(rootDirPath); if (!rootDir.isDirectory()) {     System.out.println("输入路径有误");     return; } //2.遍历目录,把指定目录中的所有文件和子目录都遍历一遍,从而找到要删除的文件 scanDir(rootDir,toDeleteName);    }    private static void scanDir(File rootDir, String toDeleteName) { //1.先列出 rootDir 中有哪些内容 File[] files = rootDir.listFiles(); if (files == null) {     //空目录     return; } //遍历当前列出的这些内容. 如果是普通文件, 就检测文件名是否是要删除的文件. //  如果是目录, 就递归的进行遍历 for (File f : files) {     if (f.isFile()) {  if (f.getName().contains(toDeleteName)) {      //不要求名字完全一样, 只要文件名中包含了关键字即可删除      // 就进行删除操作      deleteFile(f);  }     } else if (f.isDirectory()) {  //目录就递归的进行遍历  scanDir(f,toDeleteName);     } }    }    private static void deleteFile(File f) { try {     System.out.println(f.getCanonicalPath() + "确认要删除吗?(Y/y)");     Scanner scanner = new Scanner(System.in);     String choice = scanner.next();     if (choice.equals("Y") || choice.equals("y")) {  f.delete();  System.out.println("文件删除成功!");     } else {  System.out.println("文件取消删除!");     } } catch (IOException e) {     e.printStackTrace(); }    }}

 运行结果


 

 6.文件的复制

import java.io.*;import java.util.Scanner;//复制文件public class Test12 {    public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入要拷贝的原路径文件"); String src = scanner.next(); System.out.println("请输入要拷贝的目标路径"); String dest = scanner.next(); File srcFile = new File(src); if (!srcFile.isFile()) {     System.out.println("输入的原路径不正确");     return; } // 此处不太需要检查目标文件是否存在. OutputStream 写文件的时候能够自动创建不存在的文件. // 2. 读取源文件, 拷贝到目标文件中 try (InputStream inputStream = new FileInputStream(src)) {     try (OutputStream outputStream = new FileOutputStream(dest)) {  // 把 inputStream 中的数据读出来, 写入到 outputStream 中  byte[] buffer = new byte[1024];  while (true) {      int len = inputStream.read(buffer);      if (len == -1) {   //读取完毕   break;      }      // 写入的时候, 不能把整个 buffer 都写进去. 毕竟 buffer 可能是只有一部分才是有效数据.      outputStream.write(buffer, 0, len);  }     } }catch (IOException e) {     e.printStackTrace(); }    }}

 运行结果

 7.扫描指定目录

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

import java.io.File;import java.io.FileReader;import java.io.IOException;import java.io.Reader;import java.util.Scanner;public class Test14 {    public static void main(String[] args) throws IOException { //1.输入要扫描的文件路径 Scanner scanner = new Scanner(System.in); System.out.println("请输入要扫描的路径"); String rootDirPath = scanner.next(); System.out.println("请输入要查询的关键词"); String word = scanner.next(); File rootDir = new File(rootDirPath); if (!rootDir.isDirectory()) {     System.out.println("输入的路径非法");     return; } //2.递归遍历 scanDir(rootDir,word);    }    private static void scanDir(File rootDir, String word) throws IOException { //1.列出rootDir 有哪些内容 File[] files = rootDir.listFiles(); if (files == null) {     return; } //2. 遍历每个元素, 针对普通文件和目录分别进行处理. for (File f : files) {     if (f.isFile()) {  // 针对文件进行内容查找  if (containsWord(f,word)) {      System.out.println(f.getCanonicalFile());  }     } else if (f.isDirectory()) {  // 针对目录进行递归  scanDir(f,word);     } }    }    private static boolean containsWord(File f, String word) { StringBuilder stringBuilder = new StringBuilder(); // 把 f 中的内容都读出来, 放到一个 StringBuilder 中 try (Reader reader = new FileReader(f)) {     char[] buffer = new char[1024];     while (true) {  int len = reader.read(buffer);  if (len == -1) {      break;  }  // 把这一段读到的结果, 放到 StringBuilder 中  stringBuilder.append(buffer, 0, len);     } }catch (IOException e) {     e.printStackTrace(); } // indexOf 返回的是子串的下标. 如果 word 在 stringBuilder 中不存在, 则返回下标为 -1 return stringBuilder.indexOf(word) != -1;    }}

 运行结果