文件与IO

简介: 文件与IO

一.文件的定义

什么是文件?

文件分为狭义上的文件和广义上的文件

狭义上的文件:文件夹中的文件:包括视频、图片、文本、可执行文件等等......

其中有些文件是有后缀名的,而有一些文件是没有后缀名的

广义上的文件:在Linux系统中,所有的设备都是文件,包括键盘、网卡、硬盘.......

java中存在一个File类,通过File类创建出来的对象时java中的一个普通对象,这个文件对象在系统中不一定存在。

二.File类中常用的方法

①构造方法

1c8d949b9668cf3a6586ee291861b5ac.png

②常用方法

875a502b44244201eaea0bc30ab52b46.png

27f47718c012ce293361b8f849144785.png

8cd323c81fafc4bad4ccfb5d8e0b2c8a.png

三.文件内容的读写

我们可以观察发现:这些方法都是对文件信息进行操作:包括创建,查找,查看,删除,列表,重命名等等....,但是并没有对文件内容进行操作:对文件内容的读写则包括:(Input和Output)(读取和写出)

3.1流和数据输送:

数据传输的过程,我们可以抽象化为流传输(数据流)Stream的过程:通过下图进行理解:

image.png


我们进行文件的输入和输出的过程,我们可以理解为数据流传输的过程:比如是从原水池中传输水源到目标水池,我们中间通过缓冲站进行传输,其中,缓冲站的大小是我们可以自己定义的:比如我们传输100L的水,但是缓冲站大小为10L,那就需要分10次运输才能完成(10次IO),如果运输1000L,那么则需要100次运输才能完成


而计算机中关于这个模型的应用场景如下:

37d37b6a78d5315eced03e88344604f2.png

比如我们需要30G的内存加载到显示器,那么我们需要将内存先输入到内存,然后通过内存加载到显示器:而我们每次只能往内存中输入(Input)100M的数据,每次内存需要将这100M的数据输出(output)到显示器,再这样多次重复下,最终30G的电影最终被播放在显示器上

通过以上两个例子我们进行总结:对于计算机而言,输入和输出是相对于内存而言的,其它设备将数据送往内存叫数据的输入(input),内存将设备输送到别的地方叫数据的输出(output)。

在java中,将input和output提供了两个抽象类:InputStream(将数据输入到内存)和outPutStream(将数据从内存输出)

而系统中存在着不同类型的文件,包括:文本文件和二进制文件,针对不同的文件类型,java也提供了不同的处理类

image.png

①FileInputStream

我们有两种输入方式,一种是直接用int数据接收从文件中读取到的值,另一种是利用数组进行暂时储存

我们通过代码进行说明:

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.InputStream;

import java.util.Scanner;

 

/**

* @author tongchen

* @create 2023-02-12 21:48

*/

public class PutStream {

   public static void main(String[] args) throws IOException {

       //创建文件输入流

       InputStream fileInputStream = new FileInputStream("D:/360安全浏览器下载/test/aa/bb/test.txt");

 

       while(true){

           //每次读一个二进制字符

           int read = fileInputStream.read();

           if(read==-1){

               break;

           }

           System.out.print((char)read);

 

       }

         

 

           fileInputStream.close();

   }

}

640b0ae291263f122c20bf3abd5b3058.png

当我们采用一个一个数据进行读取时,我们发现其源码给出的范围是:-1-255,这个二进制数字是对应着

ASCII码值的,一旦超出这个范围,就有可能出现乱码问题。(由于编码方式的问题,汉字采用的是utf-8的编码方式,ASCII码的编码方式无法对汉字进行输入和输出)

0139b76adb9bc323a473bbdb8ba6df72.png

②FileOutputStream

写出的时候同样如此,我们既可以一个一个数据进行写入,同时我们也可以通过数组的方式进行写入

我们依然通过代码的方式对这两种方式进行举例:

public class exer03 {

   public static void main(String[] args) throws IOException {

       //创建文件输出流

       FileOutputStream fileOutputStream = new FileOutputStream("D:\\360安全浏览器下载\\test\\aa\\bb\\test.txt");

       //每次读入一个二进制文件

       fileOutputStream.write(69);

       fileOutputStream.write(70);

       fileOutputStream.write(71);

       //一定要注意的是:我们在写入时会将原来的数据全部清除

     

       fileOutputStream.flush();

     

       fileOutputStream.close();

   }

}

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

 

/**

* @author tongchen

* @create 2023-02-12 22:04

*/

public class exer04 {

   public static void main(String[] args) throws IOException {

       FileOutputStream fileOutputStream = new FileOutputStream("D:\\360安全浏览器下载\\test\\aa\\bb/test.txt");

       byte[]inserts=new byte[1024];

       for (int i = 0; i <127 ; i++) {

           inserts[i]=(byte) i;

       }

       fileOutputStream.write(inserts);

   }

fileoutputStream.flush();

fileoutputStream.close();

 

}

我们在往文件中写入数据时,会将文件之前的内容进行覆盖。

写入的时候我们需要注意的一个点:flush()方法,该方法用于刷新缓存区:一般而言,我们每次进行write()操作,并不是直接将数据写入硬盘中,而是先写入缓存区(避免过多次数的IO,提高效率),将缓存区写满之后再将数据存入硬盘,但是很多情况下我们需要把数据立即写入硬盘,所以需要我们手动进行刷新,将缓存区中的数据写到硬盘中。

我们再介绍一个点:关于文件手动关闭的重要性:我们都知道的是,每个进程的启动都会开辟一些资源,其中有一项是文件描述符表,我们在操作进程时打开的任何文件都是一个文件描述符,会被存入文件描述符表,我们可以将文件描述符表理解为一个数组:如果我们仅仅只是不断地往数组中加元素(文件描述符),而不进行及时地销毁,那么必然无法避免一种情况的发生:文件描述符表被填满了,这时会导致进程卡死,这时只能通过重启进程来解决,这时会导致很多数据的丢失或者其他情况,问题很严重,所以我们需要在用完一个文件之后进行关闭(将文件在文件描述符表中删除)

在write()方法中我们虽然发现源码中没有对数值范围的限制,但是事实上当我们输出的字符一旦超过ASCII码的数值范围,编码格式就会发生改变,则会产生乱码等问题,所以一般我们很少直接使用二进制流的方式向文件中输入内容,而是使用print()使用字符串和指定编码格式进行输入,从而降低出现乱码问题的可能性。

③FileReader

filereader和filewriter都是基于字符的输入输出方式,通过这种方式我们可以进行汉字的输入和输出

我们通过代码将其的使用方式进行举例:

④FileWriter

我们通过代码将其的使用方式进行举例:

import java.io.FileWriter;

import java.io.IOException;

 

/**

* @author tongchen

* @create 2023-02-12 22:07

*/

public class exer05 {

   public static void main(String[] args) throws IOException {

       //创建字符写入流

 

       FileWriter fileWriter = new FileWriter("D:\\360安全浏览器下载\\test\\aa\\bb/test.txt");

       fileWriter.write("你爱我");

       fileWriter.write("我爱你");

       fileWriter.write("相亲相爱一家人");

 

       fileWriter.flush();

       fileWriter.close();

   }

}

关于利用Scanner个和PrintWriter简化读写操作:

通过这两种方式依然可以实现对汉字的是输入和输出

public class PutStream {

   public static void main(String[] args) throws IOException {

       //创建文件输入流

       InputStream fileInputStream = new FileInputStream("D:/360安全浏览器下载/test/aa/bb/test.txt");

       Scanner scan=new Scanner(fileInputStream,"UTF-8");

       System.out.println(fileInputStream.read());

       //在文件中读取下一行

       while(scan.hasNextLine()){

           String s = scan.nextLine();

           System.out.println(s);

 

       }

          scan.close();

 

           fileInputStream.close();

   }

}

public class exer03 {

   public static void main(String[] args) throws IOException {

       //创建文件输出流

       FileOutputStream fileOutputStream = new FileOutputStream("D:\\360安全浏览器下载\\test\\aa\\bb\\test.txt");

       PrintWriter printWriter = new PrintWriter(fileOutputStream);

       //每次读入一个二进制文件

       fileOutputStream.write(69);

       fileOutputStream.write(70);

       fileOutputStream.write(71);

       //一定要注意的是:我们在写入时会将原来的数据全部清除

       printWriter.println("hdsjhdak");

       printWriter.println("死锁");

       fileOutputStream.flush();

       printWriter.flush();

       printWriter.close();

       fileOutputStream.close();

   }

}


相关文章
|
6天前
|
存储 Java API
【JavaEE】——文件IO(万字长文)
文件路径,文本文件,二进制文件,File类,文件流,字节流(InputStream,OutputStream)字符流(Reader,Writer)
|
2月前
|
Java 测试技术 Maven
Maven clean 提示文件 java.io.IOException
在使用Maven进行项目打包时,遇到了`Failed to delete`错误,尝试手动删除目标文件也失败,提示`java.io.IOException`。经过分析,发现问题是由于`sys-info.log`文件被其他进程占用。解决方法是关闭IDEA和相关Java进程,清理隐藏的Java进程后重新尝试Maven clean操作。最终问题得以解决。总结:遇到此类问题时,可以通过任务管理器清理相关进程或重启电脑来解决。
|
3月前
|
搜索推荐 索引
【文件IO】实现:查找文件并删除、文件复制、递归遍历目录查找文件
【文件IO】实现:查找文件并删除、文件复制、递归遍历目录查找文件
52 2
|
3月前
|
编解码 Java 程序员
【文件IO】文件内容操作
【文件IO】文件内容操作
62 2
|
3月前
|
存储 Java API
【文件IO】文件系统操作
【文件IO】文件系统操作
55 1
|
4月前
|
Java 大数据 API
Java 流(Stream)、文件(File)和IO的区别
Java中的流(Stream)、文件(File)和输入/输出(I/O)是处理数据的关键概念。`File`类用于基本文件操作,如创建、删除和检查文件;流则提供了数据读写的抽象机制,适用于文件、内存和网络等多种数据源;I/O涵盖更广泛的输入输出操作,包括文件I/O、网络通信等,并支持异常处理和缓冲等功能。实际开发中,这三者常结合使用,以实现高效的数据处理。例如,`File`用于管理文件路径,`Stream`用于读写数据,I/O则处理复杂的输入输出需求。
254 12
|
3月前
|
存储 Java 程序员
【Java】文件IO
【Java】文件IO
43 0
|
4月前
|
Linux C语言
C语言 文件IO (系统调用)
本文介绍了Linux系统调用中的文件I/O操作,包括文件描述符、`open`、`read`、`write`、`lseek`、`close`、`dup`、`dup2`等函数,以及如何获取文件属性信息(`stat`)、用户信息(`getpwuid`)和组信息(`getgrgid`)。此外还介绍了目录操作函数如`opendir`、`readdir`、`rewinddir`和`closedir`,并提供了相关示例代码。系统调用直接与内核交互,没有缓冲机制,效率相对较低,但实时性更高。
|
5月前
|
存储 监控 Linux
性能分析之从 IO 高定位到具体文件
【8月更文挑战第21天】性能分析之从 IO 高定位到具体文件
56 0
性能分析之从 IO 高定位到具体文件
|
5月前
IO流拷贝文件的几种方式
IO流拷贝文件的几种方式
42 1