JavaWeb之IO初认知

本文介绍了计算机的IO原理,包括硬件结构、硬盘存储和文件系统。详细讲解了内存、硬盘的访问速度以及文件的基本知识,如文件的类型、路径表示和文件操作。在Java中,通过File类实现了文件的创建、删除等基本操作,并探讨了文件操作的实际应用。
摘要由CSDN通过智能技术生成

目录

IO原理

1. 计算机体系结构  

2. 硬盘——存储

计算机存储常识 

各个存储访问速度的一个直观感受 

文件基本知识

小结

3. 在Java中,实现基本的IO操作

通过Java 代码操作文件(File)

创建

删除

本篇小结


IO原理

1. 计算机体系结构

2. 硬盘存储——文件操作

3. 在Java中,实现基本的IO操作

1. 计算机体系结构  

硬件:处理器(CPU)、存储器(内存)、输入设备(Input Device)、输出设备(Output Device)

其中CPU只能和内存做直接的数据交换。

Input Device:现实中的物理信号(光信号、电信号、波信号)->数字个数,存储在内存中。Output Device:数字->物理信号

IO设备:显示器(O)、触屏显示器(IO)、鼠标(I)、键盘(I)、摄像头(I)、麦克风(I)、扬声器(O)

           硬盘(IO)、网卡(IO)

2. 硬盘——存储

计算机存储常识 

易失存储:

1.断电后丢失
2.以进程为单位管理

变量、对象本质上的编程语言对硬件中内存的抽象

持久存储:

1.断电后一般仍能保存

2.通常可以跨进程读写

各个存储访问速度的一个直观感受 

内存(Memory):又被称为RAM(Random Access Memory)。
支持以O(1)时间复杂度,根据下标(内存地址)访问的存储。

硬盘

硬盘的实现Hard Disk Drive (HDD)

1. 磁盘(利用磁性实现的一种存储方式)、硬盘(机械硬盘)

    磁盘寻址:磁盘更适合做连续数据的读写,而不适合做随机数据的读写。

2. 固态硬盘(Solid State Disk SSD)
3. 闪存(Flash Memory)

软件层面认识硬盘中的数据

硬盘数据的读写->文件的读写问题
由OS+文件系统(FileSystem),统一管理文件。

文件基本知识

我们看到的文件的基本知识


1. 文件被以树形结构(数据结构学过的树,但不是二叉树)进行管理,文件都是树上的节点(node)。

2. 文件可以大体分成两大类:
        1)存储数据的文件——普通文件(俗称的文件)
        2)管理树形结构组织数据的文件——目录/文件夹(directory / dir)

无论是目录或文件都只是树上的一个结点,一个结点可以有多个孩子。

3. 这棵文件树只是一个逻辑结构,而不是硬盘上的物理结构

a.普通文件
在Windows OS下,以文件后缀(file suffiex)来标记出这个文件存储的内容是什么内容。
如:*.txt普通文本、*.docx Word文档等。

b. 可见or隐藏

文件:包括目录、文本文件、不是文本的文件(二进制文件)。
例如:a.txt、a.java(文本),a.class、a.png(二进制)。

关于文件的路径(Path):根据一个规则,从文件树上唯一确定一个位置,这个位置一定对应到某个结点,但是这个结点可以不存在。

路径:
1. 绝对路径(absolute path abs path):从一棵树的根结点出发描述的路径。
2. 相对路径(relative path ):从“我们”所在的当前位置出发。描述的路径。

无论“我们”身在何处,总是唯一确定一个位置。

什么叫做“我们”所在的位置:每个进程都有一个当前工作目录(current working directory ,cwd),一般一个进程的启动目录,就是当前工作目录。

真实中怎么去描述路径(重点):windows 下,先以绝对路径为例


在代码的字符串中如何表示这个路径

String path ="D:\Java\截图.png";

直接这么写的错误的,因为字符串中反斜杠\,表示转义的意思比如\n \t 等。

应该写作:使用\\转义后表示\

String path = "D:\\Java\\截图.png";

Windows 使用 \ 作为路径分隔符,Linux(Unix/XOS)使用 / 作为路径分隔符。

Java号称跨平台,所以可以帮我们处理这个问题,代码中写"/或者“\\”都可以,一般使用"/”为主。写作如下,同样正确。

String path = "D:/Java/截图.png";

路径表示中的两个特殊的符号一个点(".")和两个点(" ..")
其中:

"."表示在当前位置(目录)不动
".."表示回到当前位置的父结点(目录)上

这两个符号一般在相对路径上使用较多

我现在在C:/Windows/Users下
../../a.txt     表示C:/a.txt
./hello.jpg  表示C:/Windows/Users/hello.jpg
hello.jpg    表示C:/Windows/Users/hello.jpg

此处C:/Windows 等价于C:/Windows/ (前提Windows是个目录)

相对路径:
1.最基本的相对路径
进程运行时的工作目录在哪里?
current working diretory(cwd)

JVM下,通常就是进程启动时的目录!
注意,原则上是启动时的目录,而和代码/工程所在目录无关。
开发阶段:开发编译
运行阶段:程序运行变成进程

小结

关于文件的路径:
1. 路径是树上找到一个结点的位置

2. 路径存在并不表示文件一定存在

3. 路径分为绝对路径or相对路径

4. 当前位置:进程的当前工作目录
5. 文件路径"/"或者"\\"表示路径分隔符,Java下使用哪个都可以

6. "."和".."的含义

树的结点分为:叶子结点和非叶子结点
普通文件:只能是叶子结点
目录文件:叶子结点or非叶子结点都可以,处于叶子节点时是空目录

数据结构中学过树:结点的操作更容易、子树的操作更复杂
文件系统中,以结点为单元进行操作(在代码层面)
文件移动操作(文件重命名、文件剪切+粘贴):结点的移动(重命名or移动到其他结点下)。

文件复制操作(复制+粘贴):新建结点+内容的复制。

目录移动操作(目录重命名、目录剪切+粘贴):以该结点为根的一棵子树的移动
目录复制操作:以该结点为根的一棵子树的复制

删除:默认情况下只能删除普通文件or空目录。只能删除结点,不能删除子树

删除非空目录:对以当前目录为根整棵子树的删除

树的操作,需要转换成结点的操作:

以目录的复制为例,遍历(深度or广度)整棵树,然后对其中的每个结点进行复制。

3. 在Java中,实现基本的IO操作

通过Java 代码操作文件(File)

文件数据 = 元数据+内容数据

我们只关注元数据本身,暂时不管内容数据。
对文件系统树的操作:判断是否存在、判断是否是目录、创建、删除、重命名....

File对象描述一个文件(结点,结点对应的文件是否存在并不一定)

创建

创建一个新文件返回true:创建成功
返回false:创建失败(文件已经存在)
抛出IOException:发生了IO 异常(最常见的,是文件应该在的目录现在还不存在)
如:D:\\学习\\Java\\new\\hello.txt

import java.io.IOException;

public class Demo1 {
    public static void main(String[] args) {
        // 1. 绝对路径的方式创建
        // 1.1 直接传入字符串的路径
        File file1 = new File("D:/学习/Java/hello.txt");
        // 1.2 传入父路径 + 子路径
        File file2 = new File("D:/学习/Java","hello.txt");
        // 1.3 以 File 传入 parent
        File parent = new File("D:/学习/Java");
        File file3 = new File(parent,"hello.txt");

        // 负数代表 file1 < file2
        // 0 代表 file1 == file2
        // 正数代表 file1 > file2
        int cmp1 = file1.compareTo(file2);
        int cmp2 = file2.compareTo(file3);
        System.out.println(cmp1);
        System.out.println(cmp2);
    }
}

import java.io.IOException;

public class Demo1 {
    public static void main(String[] args) throws IOException {
        File file4 = new File("D:/学习/Java/hello.txt");
        boolean r1 = file4.createNewFile();
        System.out.println(r1);// 这里打印 true
        // 异常的知识点:Java 中的异常分为 
        // 受查异常(checked exception) or 非受查异常(uncheck exception)
        // 方法中如果可能抛出受查异常,有语法要求
        // 要么,我们自己 try catch,不再抛出受查异常
        // 要么,在方法签名中通过 throws 声明有受查异常可能被抛出
        // java.lang.RuntimeException 及其子类是非受查异常
        // java.io.IOException 是受查异常
        r1= file4.createNewFile();
        System.out.println(r1);// 由于文件被创建过了,所以是 false
    }
}

删除

delete() vs deleteOnExit()
delete:立即删除
deleteOnExit:在JVM退出时才真正删除

1. 普通文件删除(存在)

import java.io.File;
import java.io.IOException;
public class Demo2 {
    public static void main(String[] args) throws IOException {
        File file1 = new File("D:/学习/Java/deleteTxt.txt");
        boolean r = file1.delete();
        System.out.println(r);
    }
}


2. 普通文件删除(不存在)

import java.io.File;
import java.io.IOException;
public class Demo2 {
    public static void main(String[] args) throws IOException {
        File file1 = new File("D:/学习/Java/deleteTxt.txt");
        boolean r = file1.delete();
        System.out.println(r);
    }
}


3. 空目录删除(存在)

import java.io.File;
import java.io.IOException;
public class Demo2 {
    public static void main(String[] args) throws IOException {
        File file2 = new File("D:/学习/Java/deleteDirectory");
        boolean r = file2.delete();
        System.out.println(r);
    }
}


4. 非空目录删除(必须递归解决)

import java.io.File;
import java.io.IOException;

public class Demo2 {
    public static void main(String[] args) throws IOException {
        File file2 = new File("D:/学习/java/test");
        traversal(file2);
    }

    private static void traversal(File dir) throws IOException {
        File[] files = dir.listFiles();
        for (File file : files)
            if (file.isDirectory()) {
                System.out.println(file.getCanonicalPath() + "\\");
                traversal(file);
                // 当深度优先的遍历完成时,则可以认为该目录一定是空目录了
                file.delete();
            } else {
                // 得到这个文件的一个标准(去除一切无意义的“.”和“..”)
                System.out.println(file.getCanonicalPath());
                file.delete();
            }
    }
}

删除非空目录
1. 先遍历(深度优先——递归),删除这个目录下的所有子孙,让这个目录变成空目录

2. 删除该目录

File类常见方法总结
一、构造方法绝对路径or相对路径

二、判断文件属性
1.是否存在exists()
2.是否是目录isDirectory()

3.是否是普通文件isFile()

三、获取文件标准路径
1.getCanonicalPath() throws IOException

四、对于文件树结构的修改
1.创建结点
        1)创建目录mkdirs()        2)创建普通文件createNewFile()

2.删除结点delete()
3.移动结点(重命名结点)        renameTo()

五、针对目录,可以获取目录下的所有孩子文件
listFiles()        如何对一棵树进行遍历(深度优先(更常见)or 广度优先)


JDK中只提供了针对结点的操作,没有提供针对一棵树的操作。
一切针对树的操作,都需要我们写代码自己搞定!

delete()是不进入回收站的删除,是真正的删除。
windows 上的回收站的删除,实际上只是把文件剪切到一个固定目录。

本篇小结

1. IO设备(数据必须经由IO设备处理并加载到内存之后才能被CPU处理)

2. 硬盘设备(存储的常识:读写速度、易失性等)
3. 文件系统(文件是硬盘数据的抽象)
        树形结构、路径、目录or普通文件

4. 文件数据=管理数据+内容数据
        java.io.File对象
5. createNewFile() + delete()

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瘦皮猴117

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值