Java中的IO操作

article/2025/10/5 14:51:45

     IO 操作是我以前不太理解的操作。总是觉得很神奇,然后一脸懵逼。今天终于鼓起勇气,认真的学习IO方面的知识。有理解不妥当或者不正确的地方,还请各位大佬指正。

一、java的io发生在哪?

      这个问题,我们必须首先明确下。io发生在内存和硬盘之间。因为程序在内存中运行。我们需要将硬盘的文件数据读入到内存中,再将数据从内存输出到硬盘中,所以我们就有了IO操作。i和o是分别代表(input和output)。输入和输出,都是我们站在内存的角度看的。不要弄混了哦。

二、java中的IO类

在提IO具体类之前,我们需要先了解下文件类,因为我们需要从硬盘的文件读入流数据或者写出流数据。所以我们需要先让我们的一个对象指定对应的文件。

java中的IO类主要分为两大类:节点流类和处理流类。下边我来分别讲述这两类中的流类.

  1.java中的节点流:节点流分为字节流和字符流。

           (1)字节流为FileInputStream(输入)和FileOutputStream(输出)两个类。在字节流中,我们通常用字节数组(byte[ ])来作为运输这些字节流的载体。

           (2)字符流为FileReader(读入)和FileWriter(写出)两个类。在字符流中,我们通常用字符数组(char[ ])来作为运输这些字节流的载体。

            (3)看一个例子的代码实现(读入和写出字符的,输入和输出字符的同理)。

public void oop11() {
File iipp = new File("C:\\Users\\er\\Desktop\\2.txt");     //在这,我们使得iipp这个对象关联C:\\Users\\er\\Desktop\\2.txt这个文件。必须要用双斜杠哦,因为单斜杠是转义字符。
File iipp1 = new File("C:\\Users\\er\\Desktop\\5.txt");            //如果有,就关联,没有就先创建后再关联(有输出流的方法中)。
FileReader fr = null;
fr1 = null;
try {
         fr = new FileReader(iipp);                      //在这我们创建读入2.txt的字符流对象

fr1 = new FileWriter(iipp1);                     //在这我们创建输出到5.txt的字符流对象

                        char[ ] kk = new char[25];                        //创建char类型的数组,用来运输字符

int len;                                                   

while ((len = fr.read(kk)) != -1) {            //参考javaApi中描述:read方法返回值为:The character read, or -1 if the end of the stream has been reached (读入的字母或者当到达流的末尾后返回-1),所以我们用while函数,当它不能于-1时,就一直读。

  fr1.write(kk, 0, len);             //写出数组中从第0个开始到第len个(因为我们已经读了这么多呀。)          
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();

}

             finally {if(fr!=null && fr1!=null) {            //如果这两个流都为null,则说明没有进行流的赋值,则需要重新赋值,不能关闭。如果为null,则说明我们上边的程序已经执行完毕。用完流后,需要将流关闭。

                      try {
fr.close();                      // 关闭输入和输出流,关闭的先后顺序无所谓。  
fr1.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();

}
}}
}

       做个比喻,当我们用字节流或者字符流时,我们相当于在内存和硬盘中的文件(File形参)之间搭起了一座单向的路,同时这个路有相关的路政机构(流类中的方法),他们在硬盘与内存的接口,负责数据的读写工作。通常情况下,我们选择用数组来装载运输数据,就像大卡车一样运输货物一样。我们根据目标文件的大小来选择卡车的大小(byte或者char数组的长度),输出到控制台或者文件中。就像下图描述的这样。

 

2..java中的处理流:很多。在这我们只说两种处理流:缓冲流(能大幅增加程序读写文件的效率)和对象流(这个流给我的感觉就是很可爱,我也不知道为啥是这种感觉~)。

   (1)缓冲流:先看java API中的定义:When the BufferedInputStream is created, an internal buffer array is created. As bytes from the stream are read or skipped, the internal buffer is refilled as necessary from the contained input stream, many bytes at a time.(当创建了缓冲流时,我们也就创造了一个额外的缓冲区。当流中的字节被读或者转移的时候,这个缓冲区就被填充满,一次可以填充很多字节)。另补充下,缓冲区位于内存之中,在java中大小一般为8M,这样我们一次就可以读入或者输出8m的字节,相比于一次一个数组,我们肯定快了许多。内存和内存之间的传输相比于内存与硬盘的传输也快了许多。

    (2)缓冲流的分类:BufferedInputStream/ BufferedOutputStream 类(字节的输入输出)和BufferedReader/ BufferedWriter(字符的输入输出)类。接下来我们仍然需要看代码实现。

     public void oop12(String dec,String hh) {

File iipp1=new File(dec);      //此处dec和hh都为包含路径的文件名
File iipp3=new File(hh);
FileInputStream uup=null;              //初始化字节的输入输出及缓冲流为null
BufferedInputStream aa=null;
FileOutputStream uup2=null;
BufferedOutputStream aa2=null;
try {
uup=new FileInputStream(iipp1);          //将字节输入流搭在dec文件上(换种说法就时是创建dec文件到内存的流)
aa= new BufferedInputStream(uup);     //创建uup的缓冲流(缓冲流只能建立在节点流之上,不能直接接在文件上)
uup2=new FileOutputStream(iipp3);      
aa2= new BufferedOutputStream(uup2);
byte[]  yy=new byte[200];                        //创建字节数组
int len;
while((len=aa.read(yy))!=-1) {               
aa2.write(yy,0,len);
                       aa2.flush();                               //将缓冲区的数据强行冲到文件中,之所以有这个函数,是担心有缓冲区的数据没有被输出,导致数据丢失。

}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
if (aa!=null&&  aa2!=null) { 
  try {aa2.close();

     aa.close();                     //只需要关闭Buffer的流就行了,关闭它,就已经关了节点流。

                     aa2.close();

 } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}}}

}

综上,我们仍然可以画个图来表示这个过程。


当我们读入这个文件时,我们会首先创建个缓冲区,这个缓冲区一次从流中读入8M数据到内存(java中通常设置),

然后我们再通过数组对缓存中的数据进行读取。当我们要写出文件时,我们会首先创建个缓冲区,然后通过数组的形

式写到这个缓冲区里,等缓冲区到了8M,直接送出内存到硬盘。就像我们单独用节点流,每次都只转移一个数组的

数据,通过缓冲,我们一次转移8M。效率会大大增加。就像我们最开始是用卡车来回运输货物,现在开始用卡车先

装到距离我们最近的航空母舰上,(额,远洋货轮上),再送,效率肯定会有很大提升。

(3)对象流:之所以谈这个流,是觉得这个流特别有意思。来先看API:An ObjectOutputStream writes

primitive data types and graphs of Java objects to an OutputStream. The objects can be read (reconstituted

) using an ObjectInputStream. Persistent storage of objects can be accomplished by using a file for the

stream. If the stream is a network socket stream, the objects can be reconstituted on another host or in

another process. (一个输出的对象流输出原始的数据类型和对象的结构,我们可以用输入对象流来读这个对象,

如果想永久的保存的话,我们可以将它保存到一个文件中,如果这个流是网络套接字流的话(网络传输),我们可

以再另一台主机或者进程中将其再生(重新使用))。就是说我们通过这个对象流,可以保存、输入、输出我们一个类

的对象!很好玩的事情,虽然我目前还不知道具体应用。来继续看其代码实现。

       class  ooo implements Serializable {  //在这我们造了类,后边实现Serializable(序列化),没有序列化,就不能使用对象流。
Integer a=5;                       //类中不能有static(静态的)和transient (短暂的)关键字修饰的变量
       @Override
public String toString() {
return "ooo [a=" + a + "]";
}

}

public class io2 {
public void testobject() {
ooo u=new ooo();
ObjectOutputStream oos=null;
ObjectInputStream ooss=null;
try {
oos = new ObjectOutputStream(new FileOutputStream("ss.txt")); //我们将输出流搭在ss.txt(相对路径)
oos.writeObject(u); //写入u对象
oos.flush();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {if(oos != null) {
try {
oos.close(); //关闭流
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}}}
}

3.需要注意的一点:流用完之后记得关闭。要不然会造成内存和cpu性能的浪费,甚至硬盘的数据填满。

over~,这次就这些喽。周末愉快,小宝贝们。


http://chatgpt.dhexx.cn/article/J3ckK2yJ.shtml

相关文章

基础IO-文件IO操作

目录 1.C语言文件IO相关操作(库函数IO接口) 2. 系统调用IO接口 1.C语言文件IO相关操作(库函数IO接口) fopen--打开文件,返回一个文件的操作句柄,有了句柄才能对指定的文件进行操作。 FILE *fopen(char *p…

Java文件IO操作

目录 一、了解什么是文件 狭义的文件: 广义的文件: 二、文件的路径 ①文件的绝对路径 ②文件的相对路径 三、Java对于文件的操作 File类的构造方法 File类的普通方法 四、对于文件的内容操作 ①FileInputStream(文件输入流&#xf…

IO操作

一、简介 IO流是用来处理设备之间的数据传输的,数据一般储存在设备上 设备:硬盘,光盘,内存等等,内存是临时储存的 Java对数据的操作是采用流的方式 按照操作的数据分为:字节流和字符流 暗照流向&#x…

Java基础--IO操作

一、IO原理及分类 一、IO原理 1、I/O是Input/Output的缩写,I/O技术是非常实用的技术,用于处理设备之间的数据传输,如读写文件,网络通信等。 2、java程序中对于数据的输入/输出操作一般都是以流的方式进行 3、java.io包下提供各…

关于I/O操作

https://blog.csdn.net/deram_boy/article/details/51191425 提及这个,就想到了各种文件操作,这种流,什么reader 啊, writer啊,buffer啊,file啊。但是综合的东西与总结,只是曾经了解。因为工作…

IO操作概念

IO:输入输出,对程序的输入与输出 文件:一组有关数据的集合 文件名:这组数据的名字 linux系统中所有文件均属于文件(通过文件系统进行管理) 按类型分类: 1、普通文件 (…

I/O操作

前言 I/O操作即操作存储器,所以想了解I/O操作,需要了解一点存储器相关知识点。 计算机存储器 存储器是计算机的核心部件之一,在完全理想的状态下,存储器应该要同时具备以下三种特性: (1)速度…

操作系统_04_IO相关(个人总结)

声明: 1. 本文为我的个人复习总结, 并非那种从零基础开始普及知识 内容详细全面, 言辞官方的文章 2. 由于是个人总结, 所以用最精简的话语来写文章 3. 若有错误不当之处, 请指出 软硬链接 软链接(快捷方式): 删除原文件时, 软链接则失效 硬链接…

gcc 命令

gcc 命令 GCC 编译器 gcc 命令格式 gcc 选项 文件名字主要选项 -c&#xff1a; 只编译不链接为可执行文件&#xff0c;编译器将输入的.c 文件编译为.o 的目标文件。-o&#xff1a; <输出文件名>用来指定编译结束以后的输出文件名&#xff0c;如果不使用这个选项的话 G…

Ubuntu Linux gcc的常用命令

目录 一、gcc简介 二、简单的gcc编译 1 预处理 2 编译为汇编语言代码 3 汇编 4 连接 三、多个程序文件的编译 四、检查错误 五、连接库文件 1 编译成可执行文件 2 链接 3 强制链接时使用静态链接库 六、总结 一、gcc简介 Linux系统下的Gcc&#xff08;GNU C Compi…

Linux GCC 编译详解

文章目录 一、GCC 编译器简介二、GCC 工作流编程语言的发展GCC 工作流程gcc 和 g 的区别 三、使用 GCC 编译GCC 编译格式GCC 编译流程多个源文件编译 一、GCC 编译器简介 首先&#xff0c;什么是编译器呢&#xff1f; 我们可以使用编辑器&#xff08;如 linux 下的 vi、window…

gcc编译命令的常用选项——强烈推荐大家使用 -Wall 选项

C程序编编译的过程分为如下四个阶段 1.预处理&#xff1a;头文件展开&#xff08;#include&#xff09;、宏替换&#xff08;#define&#xff09;、条件编译&#xff08;#ifdef&#xff09;(.i)使用预处理器&#xff08;预处理阶段处理的都是以#开头的代码&#xff09; 2.编译…

Linux(gcc编译原理、过程以及常用调试命令)

PS&#xff1a;红色字体表示重点&#xff0c;绿色字体表示重要标题&#xff0c;块引用中表示Linux终端中的命令。 1.gcc / g的安装 命令&#xff1a;sudo apt install gcc /gcc 2.gcc编译连接 //main.c文件 &#xff08;1&#xff09;预编译 ①删除所有的“#define”&#…

Linux中gcc编译步骤

我们这里以C语言为例&#xff0c;看看C语言程序在Linux中编译执行的详细步骤 1.创建一个.c文件 2.写入一些简单的代码 我们使用gcc -E filename.c -o filename.i 命令对程序先进行预处理&#xff1a;处理头文件、宏定义&#xff0c;接下来我们修改一下头文件&#xff0c;使用错…

Linux GCC常用命令

目录 一、示例一 1.简单编译 1.1预处理 1.2编译为汇编代码 1.3汇编 1.4连接 2.多个程序文件的编译 3检错 4库文件连接 二、示例二 1.准备hello.c 2.预处理 3.编译 4.汇编 5.链接 6.分析ELF文件 6.1ELF文件的段 6.2反汇编ELF 一、示例一 1.简单编译 创建文件mkd…

GCC编译过程及基本命令总结

一、GCC简介 GCC即GNU Compiler Collection&#xff0c;原本只是针对C语言的编译工具&#xff0c;现在已经变成了一个工具集&#xff0c;包含了C、C、JAVA等语言的集合体。 管理和维护&#xff1a;由GNU项目负责。 二、GCC对C、C的编译流程 (1) 预处理&#xff08;Preproce…

Linux 下的 gcc 编译常用命令

gcc&#xff1a;Linux下的一款编译器。 gcc工作流程&#xff1a; 完整编译流程&#xff1a; 创建一个c语言源文件&#xff1a; gcc -E hello.c -o hello.i&#xff08;头文件展开&#xff0c;进行源文件中的宏替换&#xff0c;注释过滤&#xff09; gcc -S hello.i -o hello.…

GCC命令编译

1.GCC编译过程&#xff08;原理如下&#xff0c;使用命令请见2&#xff09; 从 hello.c 到 hello(或 a.out)文件&#xff0c; 必须历经 hello.i、 hello.s、 hello.o&#xff0c;最后才得到 hello(或a.out)文件&#xff0c;分别对应着预处理、编译、汇编和链接 4 个步骤&#…

gcc 命令详解及最佳实践

介绍 GCC&#xff08;英文全拼&#xff1a;GNU Compiler Collection&#xff09;是 GNU 工具链的主要组成部分&#xff0c;是一套以 GPL 和 LGPL 许可证发布的程序语言编译器自由软件&#xff0c;由 Richard Stallman 于 1985 年开始开发。 GCC 原名为 GNU C语言编译器&#…

使用GCC编译程序常用命令

一、编译器驱动程序 首先梳理一下源文件到可执行文件的整个过程&#xff0c;下面是两个源文件的组成main.c和sum.c // main.c int sum(int *a, int n); int array[2] { 1, 2 }; int main() {int val sum(array, 2);return val; }// sum.c int sum(int *a, int n) {int i, s…