IO的基本理论(基本常识)

 

目录

硬盘存储和内存存储区别

缓冲区(Buffer)技术

对数据的认识

文件

文件的几个概念

 代码部分:

 Java程序运行时的我们身处何处?

File类中的常见方法

 创建一个普通文件

创建目录

删除文件和目录

目录重命名

给定起始目录,遍历这个目录下的所有文件(普通文件&&文件名是.png)


目前Java语言比较少用于系统开发(开发系统软件),相较而言,做业务开发多一点。

I/O计算机硬件视角下,非内存数据的读写动作。当下文件(硬盘)IO为主。之前我们接触的I/O基本上都是在内存上,(System.in、System.out、System.err)。

硬盘存储和内存存储区别

硬盘存储:非易失性存储(non-volatile storage):可以在断电的时候进行数据的存储。硬盘存储是低速存储,读写速度远低于内存存储。

访问延时的直观数据:越上面读写速度越快,存储容量越小;越下面,读写速度越慢,存储容量越大。

 

易失性存储L0寄存器(Register)
易失性存储L1CPU内部的一级缓存(L1cache)
易失性存储L2CPU内部的二级缓存(L2cache)
易失性存储L3CPU内部的三级缓存(L3cache)
易失性存储L4内存RAM(Memory)
非易失性存储L5硬盘HD(Hard Driver)
非易失性存储L6脱机存储(offline storage)
非易失性存储L7网络存储/分布式存储(网盘)

非易失性+低速:为了弥合速度差,所以针对硬盘数据的读写提出了各种各样的数据结构,算法、来解决。

硬盘上的数据更适合:

1.块状读取(block):块状读取尽可能的减少读写频次。相对的字节读取就是频繁的进行读写。

2.块状更适合连续的读写,内存上的读写是随机的读写。(操作系统中的磁盘寻道就是解决这里的连续读写问题)。

缓冲区(Buffer)技术

由于硬盘存储的低速性,会有一个缓冲区技术(更多的是针对写的):减少硬盘的读写频次。

以OS为代表:会在内存中开辟出一段空间——缓冲区;

当我们进行写入操作:第一次写入100字节,第二次写入100字节,第三次写入100字节,第四次写入100字节,会先在内存中写四次,达到一定的条件后,统一的写回硬盘。以减少硬盘的读写频次。

其中,一定条件一般是指:

1.应用程序主动要求:冲刷缓冲区(flush操作);

2.定时刷新:每隔一定时间冲刷;

3.定量冲刷:满了之后必须写硬盘;

IO中进行flush是必不可少的操作,否则数据会丢失(需要考虑,遗留在缓冲区中的数据丢失问题)。

对数据的认识

在计算机硬件看来,一般把数据抽象成数字(什么进制,什么宽度);如何解释这些数据->文本、波、像素等。一般分为两类:

1.文本数据:可以按照一定的字符集编码解释成文本的数据;

2.二进制数据:不可以解释成文本;


文件

 狭义上的文件(File):一种抽象概念,表示硬盘中的数据块。

变量、对象是对内存中数据的抽象,文件是对硬盘中数据的抽象。

文件系统(FileSystem):对硬盘上的数据——文件进行直接组织和管理的一个模块。

Window的文件系统:

文件的几个概念

1.逻辑上,一个文件是由两块数据组成的; 管理数据+文件内容本身

 2.文件系统是按照树形结构进行文件组织的。

 3.目录/文件夹本身也是一种文件,是一种特殊的文件。

文件=文本文件 or 二进制文件;

文件=普通文件(文件) or 文件夹文件;

4.文件的位置(location)|路径(Path)-->非常重要的一个概念

用于定位到是哪个文件的(用树的视角看,就是树上的一个节点):

5.绝对路径(absolute path):从一棵树的根结点出发,达到对应节点但的完整路径。一个唯一的路径一定可以描述一个唯一的节点。

 Windows使用反斜杠" \ "作为分隔符(path separator):C:\Program Files\Java\a.text

程序中反斜杠需要转义,所以写在程序中:C:\\Program Files\\Java\\a.text

路径存在,并不代表文件一定存在。路径是描述树中一个可能的位置,但并不代表这个位置一定有节点。

比如:C:\Program Files\Java\abcd.txt是一个合法的路径,但文件并不存在。 

6.相对路径(relative path):相对...而言的路径,不再是从根目录出发了,从当前所在的位置/当前工作目录出发。

 

当前处于C:\Windows\目录下,要去找到上一层->Java->a.txt :..\Program Files\Java\a.text。

使用..代表回到上一层,使用.就在当前路径下。

从几个角度理解:我们身处何处?

绝对路径:D:\WH\企业管理

小结:

1.狭义上文件是关于硬盘中数据的抽象(非易失+低速->尽量减少读写频次->连续、块状读写+缓冲区)

2.文件可以分为:普通文件 or 目录文件;二进制文件 or 文本文件;

3.文件中的数据=管理数据+内容数据

4.文件时按照树形结构组织的,通过路径描述结点的方式,来唯一确定一个文件。

5.路径分为:

a.绝对路径(absolute path):从根开始进行结点描述的路径,无论身处何处,路径是唯一的。

b.相对路径(relative path):从当前位置出发,进行节点描述的路径,路径不变的情况,当前位置变化了,描述的结点也跟着变化

c:"."代表当前位置;".."代表上一层位置。

6.一个唯一的路径并不代表对应的文件一定存在。

 代码部分:

Java提供了java.io.File类:File对象就是对文件的管理数据的抽象,描述文件

通过一个路径(绝对路径or相对路径都行),来创建File对象,但是File对象被创建出来,并不代表文件存在。

import java.io.File;

public class Main {
    public static void main(String[] args) {
        {
            //以绝对路径为例
            File file = new File("D:\\WH\\企业管理\\a.txt");
            System.out.println(file);
            // 对象存在
            // 文件并不存在
        }

        {
            // 父结点,一般都是目录
            File parent = new File("D:\\WH\\企业管理");
            File file = new File(parent, "a.txt");
            System.out.println(file);
        }

        {
            // 父结点,一般都是目录
            File file = new File("D:\\WH\\企业管理", "a.txt");
            System.out.println(file);
        }
    }
}

 Java程序运行时的我们身处何处?

import java.io.File;

public class Main1 {
    public static void main(String[] args) {
        //工作目录,在IDEA中是配置出来的(进程的启动目录)
        //并不是代码一样,运行出来的结果就一样
        File file=new File("1.txt");
        System.out.println(file.getAbsoluteFile());
    }
}

进程在运行过程中,身处:D:\WH\文件\

其实这个文件不一定处于这个地方,只是因为:

1.在IDEA中配置的当前工作目录:默认是工程所在的目录,可以手动在Working directory中改变的,但一般是不会去改变它的。

 我们身处何处:是一个运行期间的概念,和代码编写的时候是没有关系的,每次运行都有自己的身处何处。我写的代码给A去运行,A在哪个目录下启动,完全是A决定,与代码编写无关,出来的结果也不一样。


File类中的常见方法

以下三个方法,判断如果File对应的文件是存在的,是否用于可执行权限,可读权限和可写权限。

 文件是被OS进行了权限管理的,以用户为单位进行管理。(普通用户/管理员用户)

 

 

 

 

 

import java.io.File;

public class Main1 {
    public static void main(String[] args) {
        //工作目录,在IDEA中是配置出来的(进程的启动目录)
        //并不是代码一样,运行出来的结果就一样
        File file=new File("1.txt");
        System.out.println(file.getAbsoluteFile());
    }
}
import java.io.File;
import java.io.IOException;

public class Main2 {
    public static void main(String[] args) throws IOException {
        File file=new File("..\\1.txt");
        System.out.println(file.getCanonicalPath());
        //存在吗
        System.out.println(file.exists());//最常见

        //是目录吗
        System.out.println(file.isDirectory());//最常见
        //是普通文件吗
        System.out.println(file.isFile());//最常见
        //是否可执行
        System.out.println(file.canExecute());
        //是否可读
        System.out.println(file.canRead());
        //是否可写
        System.out.println(file.canWrite());
    }
}

 

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

public class Main3 {
    public static void main(String[] args) throws IOException {
        File file=new File("..\\1.txt");
        System.out.println(file.getAbsolutePath());
        System.out.println(file.getCanonicalPath());
        System.out.println(file.length());
        System.out.println(file.getName());
        System.out.println(file.getParent());

    }
}

 创建一个普通文件

前提:路径对应的文件原来是不存在的

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

public class Main4 {
    public static void main(String[] args) throws IOException {
        //前提:路径对应的文件原来是不存在的
        File file=new File("..\\world.txt");
        System.out.println(file.createNewFile());
        
        //运行时会抛出异常:由于../xxx目录本身不存在,所以无法创建,以异常的形式体现
        File file1=new File("../xxx/world.txt");
        System.out.println(file.createNewFile());
    }
}

创建目录

 

import java.io.File;

public class Main5 {
    public static void main(String[] args) {
//        File file = new File("../a/b/c/d");
        //创建失败
//        System.out.println(file.mkdir());

        //一个一个去创建
//        File f1 = new File("../a");
//        f1.mkdir();
//        File f2 = new File("../a/b");
//        f2.mkdir();
//        File f3 = new File("../a/b/c");
//        f3.mkdir();
//        File file = new File("../a/b/c/d");
//        System.out.println(file.mkdir());

        //用mkdirs()一次创建多个目录
        File file = new File("../a/b/c/d");
        System.out.println(file.mkdirs());
    }
}

删除文件和目录

只是标记要删除,真正删除的时候是JVM退出的时候(deleteOnExit()),这里的删除时彻底删除,不是放到回收站。

文件删除是正常删除,目录删除要求必须是空目录。 

Windows上的回收站只是一个特殊的目录:回收站的删除其实不是彻底删,只是把文件移动到对应的目录。

目录重命名

 通过重命名的形式,把一个文件移动成另一个节点。

import java.io.File;

public class Main6 {
    public static void main(String[] args) {
        File file=new File("../hello/a.txt");
        File file1=new File("../world/a.txt");
        System.out.println(file.renameTo(file1));
    }
}

小结:

1.文件的创建:正确的前提:文件的父目录存在&&文件不存在(creatNewFile());

2.目录的创建:正确的前提:文件的父目录存在&&文件不存在(mkdir()),想连同不存在的父目录一起创建(mkdirs())

3.删除:普通文件直接删除,目录文件要求目录是空目录。


给定起始目录,遍历这个目录下的所有文件(普通文件&&文件名是.png)

List<String>保存所有的路径,本质上,遍历目录下的所有文件实际上就是树的遍历,遍历过程中对所有借点进行条件判断(深度优先遍历)。

列出目录下的所有文件的方法:

 

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class Main7 {
   static List<String> a=new ArrayList<>(); 
    
    public static void main(String[] args) {
        File file=new File("要找的文件名");
        traversal(file);
        for (String path:a){
            System.out.println(path);
        }
    }
    
    private static void traversal(File dir){
        File[] files=dir.listFiles();//该目录的所有孩子
        if(files==null){
            return;
        }
        for (File file:files){
            if(file.isDirectory()){
                traversal(file);
            }else if(file.isFile()){
                if(file.getName().equals("要找的文件名")){
                    a.add(file.getAbsolutePath());
                }
            }
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值