​ 【Java文件操作】手把手教你拿捏IO 流

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 哈喽,大家好~我是保护小周ღ,本期为大家带来的是 Java 文件操作,理解文件的概念以及,常用的操作文件的类和方法,FileInputStream 类 和 FileOutputStream  , PrintWriter  and Scnner,  Reader and Wirter 确定不来看看嘛~更多精彩敬请期待:保护小周ღ *★,°*:.☆( ̄▽ ̄)/$:*.°★* ‘

 

image.gif编辑

哈喽,大家好~我是保护小周ღ,本期为大家带来的是 Java 文件操作,理解文件的概念以及,常用的操作文件的类和方法, FileInputStream 类 FileOutputStream  , PrintWriter  and Scnner,  Reader and Wirter 确定不来看看嘛~更多精彩敬请期待:保护小周ღ *★,°*:.☆( ̄▽ ̄)/$:*.°★* ‘

image.gif编辑


一、文件的基本概念

1.1 为什么使用文件

在我们程序中输入的数据一般会随着 main() (主线程)—— 进程的结束而清空,这是因为此时的数据是存放在内存中的,程序结束,内存回收,等我们下次再次运行程序的时候又需要重新输入数据,如果我们想要将数据持续化存储,就必须依托于第三方介质,依托于硬盘,依托于数据库等等Windows中对硬盘中信息的管理和使用是以文件为单位的,Windows系统中推行万物皆文件的模式,这样对整体数据的存储、管理就有了一个统一的规范,降低了管理的复杂度。


1.2 什么是文件

文件可以认为是操作系统使用、管理数据的基本单位,是硬盘存储和管理数据的基本单位,我们想要某些相关联的数据作为一个独立的整体的进行保存,这个独立的整体就可以认为是一个文件。

百度百科:

文件后缀名也叫文件的扩展名,是用来表示某种文件所采用的机制。文件扩展名是加在主文件名后面的,用“.”分隔。不同的软件要求不同的文件格式,后缀名可以帮助用户了解文件是应该使用哪种软件打开文件。

在程序设计中从文件功能的角度分析有两种文件:程序文件,数据文件。

程序文件:包括我们编写的目标源文件(. java, . C), 目标文件 (windows环境后缀为 .obj), 可执行文件(windows环境后缀为 . exe)。我们的 . java 文件经过编译后得到一个 .class 文件,由Java JVM 解析文件。

数据文件:文件的内容不一定是程序,还可以是程序运行中读写的数据,例如程序运行时需要从内存(CPU 只能直接对内存的数据进行处理,所以要处理的数据会先从第三方介质:硬盘等读取到内存)中读取数据进行处理,将处理后的数据又写回第三方介质,那么这个过程中读取和写入数据的源头就可以称之为数据文件。

根据数据的类型可以将文件划分为 文本文件 和 二进制文件

文本文件:是指以ASCII字符集方式(也称文本方式)存储的文件,依托于某种字符集来识别,C语言中使用的是ASCll 编码,所以一个 char 类型只占 一个字节, 例如: 大写字符 A  的ASCll 编码 0110 0001  (65),Java 中使用的是 Unicode 字符集 一个char 类型两个字节,可以用来描述更多的字符,也包括中文,Unicode 字符集兼容 Utf -8 字符集,utf- 8 兼容 ASCll 字符集  但是 utf- 8 使用三个字节描述中文。

二进制文件(binary):二进制文件是按机器(即电脑)能够阅读的格式(只有0和1)进行存储的文件,所有文件都是以二进制的形式存储,文本文件不同是,它可以使用字符集来解析二进制,二进制文件反正操作系统能解析,正常人都是看不懂的,如果使用某种字符集解析(utf-8)大概率也是无法成功的,编码的规则不同,自然就无法显示,即使显示了字符,也是偶然适配了字符,是没有意义的。

以下是一个二进制文件使用 utf-8 字符集解析的信息,没有意义,但是系统可是识别出信息。

image.gif编辑

小正方块就是无法被字符集识别统一显示的信息。


1.3 文件的组织

伴随着文件越来越多,就需要一种管理文件的机制,在 Windows 系统中采用树型结构来组织管理文件夹。文件除了有数据内容之外,还有文件本身的一个信息,例如:文件名、文件类型、文件大小,文件路径、文件源地址,我们把这一块这信息称之文件的 “元信息”。

image.gif编辑

每一个文件夹对应硬盘上一块存储空间,它提供了指向对应空间的地址——子文件,可以把文件夹看作是一颗树的 Node 节点,节点中可以保存另一个节点或者是文本文件,二进制文件等等(实际上存储的是文件的元信息)。

文件夹是计算机术语也称之为 “目录” 是用来组织和管理磁盘文件的一种数据结构。

1.4 文件路径(Path)

熟悉电脑的朋友应该,Windows 不允许在同一文件下有相同类型并同名的文件。

文件命名规则:

(1)文件名最长可以使用255个字符。

(2)可以使用扩展名,扩展名用来表示文件类型,也可以使用多间隔符的扩展名。如 txt.jpg.exe是一个合法的文件名,但其文件类型由最后一个扩展名决定。

(3)文件名中允许使用空格,但不允许使用下列字符(英文输入法状态):< > / \ | : " * ?

(4)windows系统对文件名中字母的大小写在显示时有不同,但在使用时不区分大小写。

如何在文件管理系统中定位我们的唯一的文件?Windows 中不同文件夹中允许已使用的文件名,如果我们需要对文件精确定位,就需要使用文件路径了。

所谓文件路径就是从树形结构的角度来看,从根节点开始,逐渐向子节点延申,直到找到目标文件,那么找到该文件的所经过的节点,就称之为文件路径,从根节点开始扫描这种描述方式也被称之为文件的 “绝对路径”。

举个例子:D:\JAVA\JDK\bin\jave.exe 这是一个绝对路径

image.gif编辑


除了使用绝对路径定位文件,还有一种相对路径的方式,相对表示根据当前文件为根节点直至目标文件的路径,相对路径的表示方式也是我们常用的,缺点是文件路径不过精确,有时候会识别不到文件。

" . " 符号在相对路径中是一个特殊符号,表示当前目录

" .. " 符号也是特殊符号,表示当前目录中的上级目录

在相对路径的情况下要描述当前目录的上上级目录,或者级别更高的目录时,可以使用 “..\ ..\ ..\ ” 的形式,每一个 " ../ " 表示上一个目录。

在绝对路径中可以理解为以 “此电脑” 为根目录。

这一切的大前提都是建立在 Windows 操作系统的情况下,在其他操作系统的环境中可能会有所差异。


二、Java 中的文件操作

Java 中通过 java. io 包中的 File 类来对一个文件(包括目录)进行抽象的描述,File 对象是硬盘上的一个文件的“抽象”表示,为什么这么说呢,文件是存储来硬盘上的(第三方介质)的,直接通过代码操作硬盘,怕是不太友好,于是就在内存中创建一个文件对应的对象,然后我们通过操作内存中的对象,就可以间接的操作硬盘中的文件了。


2.1 File 类解析

我们从 File 类中常见的属性、构造方法和方法及其使用这几个方面来讲述。

2.1.1 构造方法

image.gif编辑


 2.1.2 方法

image.gif编辑


2.2 常用方法演示

2.2.1 文件属性

// 文件的属性
    public static void main(String[] args) throws IOException {
        File file = new File("hello_world.txt"); // 使用相对路径
        //file.createNewFile();
        System.out.println(file.exists()); // 判断文件是否存在
        System.out.println(file.isDirectory()); // 判断file 对象是否是一个目录
        System.out.println(file.isFile()); // 判断对象是否是一个普通文件
        System.out.println(file.createNewFile()); // 根据file 对象自动创建一个空文件,成功创建后返回 true
        System.out.println(file.exists()); // 判断文件是否存在
        System.out.println(file.isDirectory());
        System.out.println(file.isFile());
        System.out.println(file.createNewFile()); // 文件如果存在返回 false
    }

image.gif

image.gif编辑


2.2.2 文件路径显示

public static void main(String[] args) throws IOException {
        File file = new File("..\\hello-world.txt"); // 代码中要使用 \ 要使用转意字符
        System.out.println(file.getParent()); // 返回对象的父目录文件路径
        System.out.println(file.getName()); //返回对象的纯文本名称
        System.out.println(file.getPath()); // 返回对象的文件路径
        System.out.println(file.getAbsolutePath()); // 返回对象的绝对路径
        System.out.println(file.getCanonicalFile()); // 返回对象的修饰过的绝对路径
    }

image.gif

image.gif编辑


2.2.3  文件的删除

public static void main(String[] args) throws IOException {
        File file = new File("some-file.txt");
        System.out.println(file.exists()); // 判断文件是否存在
        System.out.println(file.createNewFile()); // 根据file 对象自动创建一个空文件,成功创建后返回 true
        System.out.println(file.exists()); // 判断文件是否存在
        System.out.println(file.delete()); // 删除这个文件,删除成功返回 true
        System.out.println(file.exists());
        file.deleteOnExit();// 标注这个文件将被删除,删除动作会到 JVM 运行结束时才会进行
    }

image.gif

image.gif编辑


2.2.4  创建目录

public static void main(String[] args) {
        File dir = new File("some-dir");
        System.out.println(dir.isDirectory()); // 判断对象是否是一个目录
        System.out.println(dir.isFile());// 判断对象是一个普通的文件
        System.out.println(dir.mkdir());// 创建file 对象的目录
        System.out.println(dir.isDirectory());
        System.out.println(dir.isFile());
        dir.mkdirs();// 可以创建中间目录, mkdir 只能创建单极目录
    }

image.gif

image.gif编辑


2.2.5  文件的重命名

image.gif编辑

image.gif编辑

运行结果博主已经验证,helloWorld,被创建博主手动向文件中添加了数据,最后再运行一次,renameTo() 方法,helloWorld 就替换掉成 helloWorld2 其中的数据没有丢失,重命名成功!!


三、Java 操作文件内容

第三个模块涉及的是文件内容的读写操作,学习向指定文件中写入数据,从指定文件中读取数据。

Java 标准库提供了一组类专门用于对文件进行读写操作。

针对文本文件,提供了一组类,面向 “字符流” 操作,经典代表: Reader, Writer ,读写的基本单位是字符。

针对二进制文件,提供了一组类,面向 “字节流” 操作,经典代表: InputStream, OutputStream . 读写的基本单位是字节。

3.1 文件缓冲区

先给大家补充一下 文件怎样写入信息或读出信息,当给文件写入数据时,最先应该在输出缓冲区,等缓冲区满了再输出到磁盘保存,当从文件里读取信息时,数据应先到达输入缓冲区,然后再给到程序对应的数据类型变量等。

image.gif编辑


3.2 InputStream 抽象类

InputStream 提供的抽象方法

image.gif编辑

InputStream 只是一个抽象类,关于 InputStream 的实现类有很多,基本上可以认为不同的输入设备都对应有一个 InputStream类的实现类,这里我们从文件中读取数据,可以使用 FileInputStream 类。

FileInputStream 构造方法

image.gif编辑


使用:先准备一个 hello.txt 文件,向文件内部填充一些内容:

image.gif编辑

// InputStream 字节文件读取
    public static void main(String[] args) throws IOException {
       try(InputStream file = new FileInputStream("hello.txt")) {
           byte[] buf = new byte[1024]; // 数组长度自定义,不可扩容
           while (true) {
               int data = file.read(buf);
               if(data == -1) { // 表示文件已经全部读完
                   break;
               }
               //1. 每次读取 3 字节进行 utf-8 解码,得到中文字符,utf-8 字符集一个汉字三个字节
               //2. 利用 String 的构造方法完成
               //3. data统计的是字节数
               for (int i = 0; i < data; i += 3) {
                   String str = new String(buf, i, 3, "utf-8");
                   System.out.printf("%s", str);// java 保留了C语言的打印机制
               }
           }
       }
    }

image.gif

image.gif编辑

字节流读取数据,我们想读到汉字的话巧妙的利用了 String 类的构造方法,将指定区间内(3个字节)的数据按照 utf- 8 编码集转换成字符。


3.3 Scanner 进行字符读取

上文 InputStream 针对字符进行字节流读取很不方便,还要转换,所以我们可以使用 Scanner 类将字节流读取,包装成 “字符流”,自动的转换~~

image.gif编辑

使用:先准备一个 hello.txt 文件,向文件内部填充一些内容:

image.gif编辑

// 利用 Scanner 进行字符读取
    public static void main(String[] args) throws IOException{
        try(InputStream data = new FileInputStream("hello.txt")) {
            try(Scanner in = new Scanner(data, "utf-8") ) {
                while (in.hasNext()) {
                    String str = in.next();
                    System.out.println(str);
                }
            }
        }
    }

image.gif

image.gif编辑

因为 str = in.next 遇到空格会换行,所以 world! 再第二行打印。


3.4 OutputStream 抽象类

InputStream 提供的抽象方法

image.gif编辑

OutputStream 也只是一个抽象类,关于 OutputStream 的实现类有很多,这里我们往文件中写入数据,可以使用 FileOutputStream 类,面向字节流。

image.gif编辑


使用 write() 方法向文件中写入数据

image.gif编辑

注意:博主的文件流资源会随着进程(main)的结束而结束,所以并没有手动的调用 close() 。


3.5 PrintWirter  进行字符写入

使用字节流 向文件中 “写” 数据总归是不方便的,所以可以使用 PrintWirter 将字节流数据包装成指定字符集的数据来完成输出。

PrintWriter 类中提供了我们熟悉的 print(),  println(), printf ()方法。

PrintWriter 类是基于 Reader 类实现的,关于 Reader 类稍后再讲。

// PrintWriter 字符写数据publicstaticvoidmain(String[] args) throwsIOException {
try(OutputStreamdata=newFileOutputStream("output.txt")) {
try(OutputStreamWriteros=newOutputStreamWriter(data, "utf-8")) {
// 如果想要使得每次写入的数据不被覆盖可以向构造方法中添加 truetry(PrintWriterwriter=newPrintWriter(os,true)) {
writer.println("我是第一行");
writer.printf("%d:我是第二行 \n", 1+2);
writer.print("我是第三行");
                }
            }
        }
    }

image.gif

image.gif编辑

避免二次写入文件被覆盖:

PrintWriter writer = new PrintWriter(os,true)

image.gif

这一组文件操作类,InputStream 和 OutputStream 面向字节流操作文件, read() 和 write() 也可以一次读写多个字节,使用 byte[] 数组来表示,read() 方法会尽可能的 byte[] 数组填满,如果读到文件末尾,返回 -1 , writer() 方法会把 byte[] 数组中所有的数据都写入文件。


3.6  Reader 类字符读取

// Reader 类 read 方法 以字符的形式读取publicstaticvoidmain(String[] args) {
try(Readerreader=newFileReader("hello.txt")) {
while (true) {
intc=reader.read();
if(c==-1) {
break;
                }
charch= (char)c;
System.out.print(ch);
            }
reader.close(); //释放资源        } catch (IOExceptione) {
e.printStackTrace();
        }
    }

image.gif

image.gif编辑

3.7 Writer 类字符写入

// Writer 类 writer 方法 以字符的形式写入publicstaticvoidmain(String[] args) {
try(Writerwriter=newFileWriter("output3.txt",true) ){ // true文件不覆盖写Stringstr="我的老哥";
writer.write(str);
        } catch (IOExceptione) {
e.printStackTrace();
        }
    }

image.gif

image.gif编辑


以上一组 Reader 和 Writer 类,构造方法打开文件,写入时文件不存在会自动的创建一个文件。

read() 方法来读,一次读取一个 char 或者 char[]

write() 方法来写,一次写入一个 char 或者 char[] 或者 String

close()关闭资源


到这里,Java的文件操作 IO 流博主已经分享完了,希望对大家有所帮助,如有不妥之处欢迎批评指正。

image.gif编辑

本期收录于博主的专栏——JavaEE,适用于编程初学者,感兴趣的朋友们可以订阅,查看其它“JavaEE基础知识”。

感谢每一个观看本篇文章的朋友,更多精彩敬请期待:保护小周ღ *★,°*:.☆( ̄▽ ̄)/$:*.°★*

遇见你,所有的星星都落在我的头上……

相关文章
|
3月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
1月前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
67 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
2月前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
1月前
|
Java 数据处理 开发者
揭秘Java IO流:字节流与字符流的神秘面纱!
揭秘Java IO流:字节流与字符流的神秘面纱!
35 1
|
1月前
|
自然语言处理 Java 数据处理
Java IO流全解析:字节流和字符流的区别与联系!
Java IO流全解析:字节流和字符流的区别与联系!
80 1
|
2月前
|
Java
Java文件操作
本文介绍了Java中`File`类的使用方法,包括构造方法、常见成员方法及其实现功能。`File`对象可以表示文件或文件夹,支持绝对路径和相对路径。构造方法有三种:基于完整路径、父级路径与子路径组合、`File`对象与字符串组合。成员方法涵盖判断类型、获取大小、获取路径、创建与删除文件/文件夹、获取文件列表、重命名等操作。文章通过示例代码详细展示了各个方法的应用场景及注意事项。
41 1
Java文件操作
|
1月前
|
Java
Java 中 IO 流的分类详解
【10月更文挑战第10天】不同类型的 IO 流具有不同的特点和适用场景,我们可以根据具体的需求选择合适的流来进行数据的输入和输出操作。在实际应用中,还可以通过组合使用多种流来实现更复杂的功能。
46 0
|
2月前
|
Java 大数据 API
Java 流(Stream)、文件(File)和IO的区别
Java中的流(Stream)、文件(File)和输入/输出(I/O)是处理数据的关键概念。`File`类用于基本文件操作,如创建、删除和检查文件;流则提供了数据读写的抽象机制,适用于文件、内存和网络等多种数据源;I/O涵盖更广泛的输入输出操作,包括文件I/O、网络通信等,并支持异常处理和缓冲等功能。实际开发中,这三者常结合使用,以实现高效的数据处理。例如,`File`用于管理文件路径,`Stream`用于读写数据,I/O则处理复杂的输入输出需求。
|
1月前
|
存储 Java 程序员
【Java】文件IO
【Java】文件IO
37 0
|
2月前
|
数据采集 Java 数据挖掘
Java IO异常处理:在Web爬虫开发中的实践
Java IO异常处理:在Web爬虫开发中的实践
下一篇
无影云桌面