目录

一、文件

1.1 文件的概念

1.2 文件的路径

1.2.1 绝对路径

1.2.2 相对路径

1.3 文件的分类

二、Java中操作文件

案例1

案例2

案例3

案例5

案例6

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

案例1——字节流读文件

案例2——字节流写文件

案例3——字符流读文件

案例4——字符流写文件

案例5——扫描指定文件(初级)

案例6——查找文件(进阶)

案例7——文件的复制


一、文件

1.1 文件的概念

可以大概从狭义和广义两个方向来区分文件。

从狭义上来看,存储在硬盘上的数据,以"文件“为单位,进行组织。

常见的文件大致有:  文本文件,图片,office系列,视频,音频,可执行程序......

如上图所示,其实文件夹,也称目录,其实也是一种特殊的文件。

而从广义上来讲,最典型的比如 Linux操作系统,为了实现接口的统一性,将所有的 I/O 设备都抽象成了文件的概念,使用这一理念 —— 万物皆文件。

比如网卡,从网卡中接受数据,就读这个文件,往网卡里发送文件,就写这个文件。

1.2 文件的路径

在描述文件的路径之前,我们先来了解一下目录结构,它的底层结构是n叉树。

其实路径:大致分为两种,一种是绝对路径,一种是相对路径,两者的本质其实都是反应文件在电脑上的具体位置。

1.2.1 绝对路径

如何在文件系统中如何定位我们的一个唯一的文件就成为当前要解决的问题,但这难不倒计算机科学家,因为从树型结构的角度来看;

树中的每个结点都可以被一条从根开始,一直到达的结点的路径所描述,而这种描述方式就被称为文件的绝对路径(absolute path)。

1.2.2 相对路径

除了可以从根开始进行路径的描述,我们可以从任意结点出发,进行路径的描述,

而这种描述方式就被称为相对路径(relative path);相对于当前所在结点的一条路径。

举例:

说了这么多,下面我们来举个栗子吧。

形如    D:\网易云\CloudMusic\cloudmusic.exe    就是一个绝对路径

“ D: ” 称之为盘符,而中间用 "\"来进行分割的是目录。

补充一个小知识:目录之间的分割符是可以使用 \ (反斜杠),也可以使用 /(斜杠)

相对路径就稍微显得有些复杂,因为其要需要一个基准路径(工作路径),通过它才能描述出这个文件具体在哪,简单来说,就是需要一个参考系。在日常生活中,我们知道,通过不同的参考系来观察同一个物体,得到的结果是不一样的,相对路径的计算也是这个道理。

示例:

简单难度

还是描述网易云这个软件

基准路径是D: 此时相对路径如何描述?

相对路径: 网易云\CloudMusic\cloudmusic.exe

当然也可以在前面加上   ./    变成   ./网易云/CloudMusic/cloudmusic.exe

在相对路径中,使用 . 表示”当前目录“ 。

基准路径:D:\网易云\CloudMusic

相对路径: ./cloudmusic.exe.

进阶

如果所给的基准路径的目录下没有所找的文件该怎么办?

比如:基准路径为: D:\网易云\CloudMusic\skin

可以使用 ..  来返回上级目录。

网易云的相对路径;   ../cloudmusic.exe.

当然了 如果是想通过 .. 从C盘切换到D盘,这种是不被允许的。

1.3 文件的分类

即使是普通文件,根据其保存数据的不同,也经常被分为不同的类型,我们一般简单的划分为 文本文件 和 二进制文件,分别指代保存被字符集编码的文本和按照标准格式保存的非被字符集编码过的文件。

文本文件:这类文件以文本的ASCII码形式存储再计算机中,它是以行为基本结构的一种信息组织和存储方式。

二进制文件:这类文件是以文本的二进制形式存储在计算机中,用户一般不能直接读懂它们,只有通过相应的软件才能将其执行出来,二进制文件一般是可执行文件,图形,图像,声音等等。

总结:

大家也都知道,计算机的存储在物理上是二进制的,所以文本文件与二进制文件的区别并不是在物理上的,而是逻辑上的,这两者其实只在编码上有所差异。简单来说,文本文件是基于字符编码的文件,常见的编码有ASCII编码,UNICODE编码等等。二进制文件是基于值编码的文件,你可以根据具体的场景,指定某个值是什么意思(这样的一个过程,可以看作是自定义编码)。

二、Java中操作文件

前言:Java作为一个跨平台的语言,为了统一代码,就在JVM中把不同的操作系统的操作文件的API进行了封装,Java就可以使用Java中的库代码来操作文件了。

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

下面我们先来看看 File 类中的常见属性、构造方法和方法:

属性

修饰符及类型 属性 说明
static String pathSeparator 依赖于系统的路径分隔符,String 类型的表示
static char pathSeparator 依赖于系统的路径分隔符,char 类型的表示

构造方法

签名 说明
File(File parent, String
child)
根据父目录 + 孩子文件路径,创建一个新的 File 实例
File(String pathname) 根据文件路径创建一个新的 File 实例,路径可以是绝对路径或者
相对路径
File(String parent, String
child)
根据父目录 + 孩子文件路径,创建一个新的 File 实例,父目录用
路径表示

方法

修饰符及返回
值类型
方法签名 说明
String getParent() 返回 File 对象的父目录文件路径
String getName() 返回 FIle 对象的纯文件名称
String getPath() 返回 File 对象的文件路径
String getAbsolutePath() 返回 File 对象的绝对路径
String getCanonicalPath() 返回 File 对象的修饰过的绝对路径
boolean exists() 判断 File 对象描述的文件是否真实存在
boolean isDirectory() 判断 File 对象代表的文件是否是一个目录
boolean isFile() 判断 File 对象代表的文件是否是一个普通文件
boolean createNewFile() 根据 File 对象,自动创建一个空文件。成功创建后返
回 true
boolean delete() 根据 File 对象,删除该文件。成功删除后返回 true
void deleteOnExit() 根据 File 对象,标注文件将被删除,删除动作会到
JVM 运行结束时才会进行
String[] list() 返回 File 对象代表的目录下的所有文件名
File[] listFiles() 返回 File 对象代表的目录下的所有文件,以 File 对象
表示
boolean mkdir() 创建 File 对象代表的目录
boolean mkdirs() 创建 File 对象代表的目录,如果必要,会创建中间目
boolean renameTo(File
dest)
进行文件改名,也可以视为我们平时的剪切、粘贴操
boolean canRead() 判断用户是否对文件有可读权限
boolean canWrite() 判断用户是否对文件有可写权限

代码示例:

案例1

import java.io.File;
import java.io.IOException;public class demo1 {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());System.out.println(f.getAbsolutePath());System.out.println(f.getCanonicalPath());}
}

运行结果:

当传入File这个类中是绝对路径时,我们可以发现 好像后三个 路径的方法 得到的结果是相同的。

但是只要我们稍微一修改代码(改成一个相对路径)就能看出他们的区别:

小补充一手:

如果是在idea上运行程序,基准路径就是项目所在目录。

解释:通过路径字符串创建文件对象,创建文件对象时不会自动创建文件。

案例2

运行结果:

案例3

运行之后,发现./test.txt 被删除了。

案例4

mkdirs() 是可以:创建多层目录。

案例5

修改目录

案例6

list的应用

总结:上述的文件操作,主要都是在操作”文件系统“。(新增文件,删除文件,列出文件目录,重命名,获取路径)。

而不是针对文件内容的操作,而针对文件内容的操作,有读文件,写文件等。

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

在Java的标准库中,就在流的概念上,提供了一组类,用于完成文件的读写操作。

它们分别为字节流(以字节为基本单位)和字符流(以字符为基本单位),前者一般适用于二进制文件,后者适用为文本文件。

字节流大致分为InputStream,OutputStream。

字符流大致分为 Reader,Writer。

以上都为抽象类,实际运用过程需要作为父类被继承使用。

InputStream 概述

方法

修饰符及
返回值类
方法签名 说明
int read() 读取一个字节的数据,返回 -1 代表已经完全读完了
int read(byte[] b) 最多读取 b.length 字节的数据到 b 中,返回实际读到的数
量;-1 代表已经读完了
int read(byte[] b,
int off, int len)
最多读取 len - off 字节的数据到 b 中,放在从 off 开始,返
回实际读到的数量;-1 代表已经读完了
void close() 关闭字节流

InputStream 只是一个抽象类,要使用还需要具体的实现类。关于 InputStream 的实现类有很多,基本可以认为不同的输入设备都可以对应一个 InputStream 类,我们现在只关心从文件中读取,所以使用 FileInputStream。

案例1——字节流读文件

读取文件内容,需要在操作前在目录中创建一个bbb.txt文件

public class demo7 {public static void main(String[] args) throws IOException {//打开文件InputStream inputStream = new FileInputStream("./bbb.txt");while (true) {int a = inputStream.read();//因为读完了返回-1,所以这里判断,如果是-1则跳出循环if (a == -1) {break;}System.out.println(a);}
//注意这里一定要进行文件的关闭,否则后续太多未关闭可能造成服务器宕机等。inputStream.close();}
}

运行结果:

这里打印的数字,与bbb.txt里面的字符一一对应。(因为此处是英文字符,每个英文字符对应一个字节,用ASCII码值表示)。

案例2——字节流写文件

OutputStream 概述

修饰
符及
返回
值类
方法签名 说明
void write(int b) 写入要给字节的数据
void write(byte[]
b)
将 b 这个字符数组中的数据全部写入 os 中
int write(byte[]
b, int off,
int len)
将 b 这个字符数组中从 off 开始的数据写入 os 中,一共写 len 个
void close() 关闭字节流
void flush() 重要:我们知道 I/O 的速度是很慢的,所以,大多的 OutputStream 为
了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的
一个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写
入设备中,这个区域一般称为缓冲区。但造成一个结果,就是我们写的
数据,很可能会遗留一部分在缓冲区中。需要在最后或者合适的位置,
调用 flush(刷新)操作,将数据刷到设备中

对文件进行写操作。OutputStream 同样只是一个抽象类,要使用还需要具体的实现类。我们现在还是只关心写入文件中,所以使用 FileOutputStream。

可以观察到,运行结束后,原先在bbb.txt中存储的hello world 被替换为97(a),98(b),99(c)。这是因为在使用OutputStream进行写文件操作时,只要打开文件成功,就会将文件原有的数据清空。

案例3——字符流读文件

public class demo2 {public static void main(String[] args) throws IOException {//使用字符流读文件Reader reader = new FileReader("./bbb.txt");while(true) {int ret = reader.read();if (ret == -1) {break;}char ch = (char)ret;System.out.println(ch);}reader.close();}
}

运行结果;

针对文本文件,使用字符流的时候,还可以使用Scanner来进行读取操作

案例4——字符流写文件

注:这里可能会出现程序运行之后,文件并没有被写入数据的情况,针对这种情况可以在写入操作后,加一行:writer.flush()来刷新缓冲区。

上述代码有一定不合理的地方,因为如果close代码的前面抛出异常,那么close就执行不到,可能就会引发资源泄露等问题。

因此作出如下优化:

public class demo5 {
//    public static void main(String[] args) throws IOException {
//        //针对写文本文件来说,可以使用PrintWriter来简化代码
//        OutputStream outputStream = null;
//        try {
//            outputStream = new FileOutputStream("./bbb.txt");
//            PrintWriter writer = new PrintWriter(outputStream);
//            writer.println();
//            writer.println(2);
//            writer.printf("a = %d",10);
//        }finally {
//            outputStream.close();
//        }
//    }public static void main(String[] args) throws IOException {//针对写文本文件来说,可以使用PrintWriter来简化代码//利用try with resources 把关闭的对象写到try()里,当try结束,就会自动的调用//到对应对象的close方法,而且支持一个()放多个对象,多个对象的创建之间的使用,使用;分割就行try(OutputStream outputStream = new FileOutputStream("./bbb.txt")) {PrintWriter writer = new PrintWriter(outputStream);writer.println();writer.println(2);writer.printf("a = %d",10);}}
}

案例5——扫描指定文件(初级)

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

1.让用户输入必要的信息

Scanner scanner = new Scanner(System.in);System.out.println("请输入要扫描的路径:");File rootDir = new File(scanner.next());if (!rootDir.isDirectory()) {System.out.println("你输入的目录不存在");return;}System.out.println("请输入要搜索的关键词:");String toDelete = scanner.next();

2. 遍历目录,需要借助一个核心方法, listFiles()——能够把当前目录里的文件和子目录列举出来,但是有个弊端,无法把子目录里的子目录列举出来。

比如;

在D盘这个分支下,有目录及文件,这个目录下可能还有目录,如果单纯只用listFile()是不行的。

解决方案就是:

遍历listFile()的结果,判断是目录还是文件,如果是文件;直接查看文件名是否包含需要查找的词,如果是目录,递归的调用listFile().

public class demo6 {public static void main(String[] args) throws IOException {//1.让用户输入必要的信息Scanner scanner = new Scanner(System.in);System.out.println("请输入要扫描的路径:");File rootDir = new File(scanner.next());if (!rootDir.isDirectory()) {System.out.println("你输入的目录不存在");return;}System.out.println("请输入要搜索的关键词:");String toDelete = scanner.next();//2,遍历目录,需要借助一个核心方法,//listFiles()——能够把当前目录里的文件和子目录列举出来//但是有个弊端,无法把子目录里的子目录列举出来。scanDir(rootDir,toDelete);}private static void scanDir(File rootDir,String toDelete) throws IOException {System.out.println("当前访问:"+rootDir.getCanonicalPath());File[] files = rootDir.listFiles();if (files == null ) {//说明 rootDir是一个空的目录return;}for (File f: files) {if (f.isDirectory()) {//递归的调用scanDir(f,toDelete);}else {//不是目录,是文件的话,判断文件是否符合要求。checkDelete(f,toDelete);}}}private static void checkDelete(File f, String toDelete) throws IOException {if (f.getName().contains(toDelete)) {System.out.println("该单词"+toDelete+"被"+f.getCanonicalPath()+"是否要删除?(Y/N)");Scanner scanner = new Scanner(System.in);String choice = scanner.next();if (choice.equals("Y") || choice.equals("y")) {f.delete();}//如果不是则不删除。}}
}

案例6——查找文件(进阶)

刚刚上面的只查询了文件名是否包含要查找的信息,这个进阶版本是查询文件里面内容是不是包含需要查询的信息。

public class demo8 {public static void main(String[] args) throws IOException {//1.输入路径和要插入的关键词Scanner scanner = new Scanner(System.in);System.out.println("请输入要扫描的路径");File rootDir = new File(scanner.next());System.out.println("请输入要查询的词: ");String toFind = scanner.next();//2.递归的扫描目录scanDir(rootDir,toFind);}private static void scanDir(File rootDir, String toFind) throws IOException {File[] files = rootDir.listFiles();if (files == null) {return;}for (File f: files) {if (f.isDirectory()) {scanDir(f,toFind);} else {checkFile(f,toFind);}}}private static void checkFile(File f, String toFind) throws IOException {//1,先检查文件名if (f.getName().contains(toFind)) {System.out.println(f.getCanonicalPath() + "文件名中包含" + toFind);}//2.检查文件内容try(InputStream inputStream = new FileInputStream(f)) {StringBuilder stringBuilder = new StringBuilder();Scanner scanner = new Scanner(inputStream);//需要按行读取while (scanner.hasNextLine()) {stringBuilder.append(scanner.nextLine()+"\n");}if (stringBuilder.indexOf(toFind) > -1) {System.out.println(f.getCanonicalPath() + "文件内容包含" + toFind);}}}
}

案例7——文件的复制

public class demo7 {public static void main(String[] args) {//文件的复制//1.先输入要复制的文件以及把这个文件复制到哪去//2.打开源文件,按照字节读取内容,再依次写入目标文件中Scanner scanner = new Scanner(System.in);System.out.println("请输入源文件");//因为要判断文件是否存在,所以用FileFile srcFile = new File(scanner.next());System.out.println("请输入目标文件");File destFile = new File(scanner.next());if (!srcFile.isFile()) {System.out.println("输入的源文件有误");return;}if (!destFile.getParentFile().isDirectory()) {System.out.println("输入的目标文件有误");return;}//打开源文件try(InputStream inputStream = new FileInputStream(srcFile);OutputStream outputStream = new FileOutputStream(destFile)) {while (true) {int ret = inputStream.read();if (ret == -1 ) {break;}outputStream.write(ret);}} catch (IOException e) {e.printStackTrace();}}
}

Java中文件操作和IO相关推荐

  1. java中文件,java中文件操作大全

    java中文件操作大全 一.获得控制台用户输入的信息 view plaincopy to clipboardprint? / //获得控制台用户输入的信息 return throws ioexcept ...

  2. java中文件操作的工具类

    代码: package com.lky.pojo;import java.io.BufferedReader; import java.io.BufferedWriter; import java.i ...

  3. Python中文件操作(IO流)及文件备份

    IO流主要作用与计算机中的输入与输出操作,一般来说,常见的IO流操作是内存和磁盘之间的输入和输出,它是一种持久操作,将数据持久化在磁盘上 在计算机中,它只能识别0和1,因此我们的文本文件要被计算机识别 ...

  4. java中文件的操作讲解

    1.基本概念的理解 绝对路径:绝对路径就是你的主页上的文件或目录在硬盘上真正的路径,(URL和物理路径)例如: C:\xyz\test.txt 代表了test.txt文件的绝对路径.http://ww ...

  5. Java本地文件操作

    概述:Java本地文件操作,涉及到文件/文件夹的创建,文件/文件夹属性的读取与设置,文件/文件夹的重命名,目录结构的遍历,以及文件内容的读取与写入. File属于java.io.File. ---在E ...

  6. java中的NIO和IO到底是什么区别?20个问题告诉你答案

    摘要:NIO即New IO,这个库是在JDK1.4中才引入的.NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多. 本文分享自华为云社区<jav ...

  7. java中文件处理之图片_Java中的文件处理

    java中文件处理之图片 File Handing in java comes under IO operations. Java IO package java.io classes are spe ...

  8. ant java 返回,在Java中直接操作ant回测试和生成测试报告

    在Java中直接操作ant来测试和生成测试报告 Ant是大家熟悉的构建工具,一般情况下,大家都是使用build.xml文件来配置使用Ant,这样的Ant已经是十分强大的.但有些怪异的场景需求特殊,你可 ...

  9. java直接调用复制文件,java中文件复制的4种方式,java文件的复制

    java中文件复制的4种方式,java文件的复制 今天一个同事问我文件复制的问题,他一个100M的文件复制的指定目录下竟然成了1G多,吓我一跳,后来看了他的代码发现是自己通过字节流复制的,定义的字节数 ...

最新文章

  1. ECharts x时间轴不连续实现
  2. python有几种模式_python的设计模式都有哪些?
  3. 每天一道LeetCode-----将字符串拆分成有效的ip地址
  4. php post json请求参数传递_php post json参数的传递和接收处理方法
  5. linux下载pycharm_django开发-使用pycharm进行远程开发
  6. 左对齐杨辉三角python_python实现杨辉三角思路
  7. 【设计模式】适配器模式 Adapter Pattern
  8. 选考技术考计算机二级,计算机二级选考什么最简单啊```
  9. 关于「数据分析师」的一些理解
  10. nested exception is java.sql.SQLException: Data truncated for column 'PassWord' at row 72
  11. PostgreSQL 179个场景
  12. 计算机毕业论文基于Python实现的学生求职招聘兼职平台
  13. MySQL理论基础以及sql语法
  14. Informatica使用操作流程--Router(由器器)、排序、序列 使用 案例6
  15. 创新驱动国产介入医疗设备崛起 唯迈医疗携极光平板DSA亮相新疆介入放射学年会
  16. ic集成电路专业通信计算机咋选,2021年美国留学研究生EE专业详解,选校选专业必备!...
  17. 去中心化云存储技术 | CESS 的多层网络架构详解
  18. 怎么检查网站是否被挂黑链?
  19. IDEA运行tomcat时,控制台红色中文乱码的解决办法
  20. jupyter远程登陆

热门文章

  1. 阿里Java学习路线:阶段 1:Java语言基础-Java面向对象编程:第21章:抽象类与接口应用:课时94:案例分析二(绘图处理)
  2. java计算机毕业设计汽车租赁系统演示录像源码+程序+lw文档+mysql数据库
  3. 爬虫学习笔记(入门)
  4. 日本手机开发之一——运营商判别和手机种类名获取
  5. javas cript入门要了解的知识和书籍
  6. Linux实训课笔记内容
  7. 数值计算网格------学习
  8. 学计算机比较出名的技校,中国最出名的8大技校 蓝翔技校仅排第三
  9. Comsol学习---声学与振动建模-----3
  10. 怎么把文件同步到服务器,把文件同步到服务器上