文件操作与IO(3)

news2024/12/23 13:49:30

文件内容的读写--数据流

这里我们将要讲到文件操作中的重要概念--流.

之前也在C语言讲解中提到了文件流的概念---读写文件内容

分为这几步:(1)打开文件;(2)读/写文件;(3)关闭文件.

数据流主要分为字节流和字符流.

字节流:以字节为单位进行读写(代表:InputStream,OutputStream).

字符流:以字符为单位进行读写,比如utf8表示汉字--即每次读写都得以3个字节(就是一个汉字)为单位进行读写.(代表:Reader:输入;Writer:输出.)

InputStream概述

方法

修饰符及返回值类型方法签名说明
int(实际是byte)read()

读取一个字节的数据,返回值代表读取到的

字节值,返回-1代表已经完全读完了

intread(byte[] b)

最多读取b.length字节的数据到b中,返回

实际读到的数量;-1代表已经读完了

intread(byte[] b, int off, int len)

其中off是offset(偏移量),最多读取len - off字节的数据

到b中,放在从off开始,返回实际读到的数量,-1代表读完

voidclose()关闭字节流

注意:

1.byte[] b表示一个缓冲区,往往是一个内存空间,方法内部对数组内容进行修改,方法执行结束之后,方法外部,亦会生效

2.在后面两个read方法中,read会尝试把数组填满,但文件剩余长度不足以填满.但文件剩余长度不足以填满.操作硬盘,本身就是比较低效的操作.出现次数越少越好.期望借助内存减少读写硬盘次数.

3.不同于内存的自动垃圾回收机制(GC),这里的字节流必须使用close()关闭(释放了文件相关资源).原因如下:我们在之前学进程PCB(一个或多个)时,中间就有个重要的属性--文件操作符表:记录打开了哪些文件.文件操作符表如果自动扩容,会付出很大代价,对于操作系统内核要求很高:每次打开一个文件,都需要在文件操作符表中占据一个位置的.如果不关闭的话,还一直代开就会导致文件操作符表耗尽.(文件操作符表的长度有上限,当文件操作符表被耗尽之后,后续再打开文件就会失败.进一步引发一系列逻辑问题).

说明

InputStream只是一个抽象类,要使用还需要具体的实现类.关于InputStream的实现类有很多,基本可以认为不同的输入设备都可以对应一个InputStream类,我们只关心从文件中读取,所以使用FileInputStream.

FileInputStream概述

构造方法

签名说明
FileInputStream(File file)利用File构造文件输入流
FileInputStream(String name)利用文件路径构造文件输入流

代码示例

示例1

将文件完全读完的两种方式.相比较而言,后一种的IO次数更少,性能更好. 

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

//需要先在项目目录下准备好一个hello.txt的文件,里面填充一些内容
public class FileTest8 {
    public static void main(String[] args) throws IOException {
        //注意:这样使用try() {格式写的原因是因为try执行完之后可以自动调用close()方法
        try(InputStream is = new FileInputStream("hello-world.txt")) {
            while (true) {
                int b = is.read();
                if(b == -1) {
                    //代表文件已经全部读完
                    break;
                }

                System.out.printf("%c", b);
            }
        }
    }
}
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class FileTest9 {
    public static void main(String[] args) throws IOException {
        try (InputStream is = new FileInputStream("hello-world.txt")) {
            byte[] buf = new byte[1024];
            int len;
            while(true) {
                len = is.read(buf);
                if(len == -1) {
                    //代表文件已经全部读完
                    break;
                }
                for(int i = 0; i < len; i++) {
                    System.out.printf("%c", buf[i]);
                }
            }
        }
    }
}

示例2

这里我们把文件内容中填充中文看看,注意,写中文的时候使用UTF-8编码.hello-world.txt中填写"卢本伟牛逼"

注意:这里我利用了这几个中文的UTF-8编码长度刚好是三个字节和长度不超过1024字节的现状,但这种方式不是通用的.

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class FileTest10 {
    public static void main(String[] args) throws IOException {
        try (InputStream is = new FileInputStream("hello-world.txt")) {
            while(true) {
                byte[] buf = new byte[1024];
                int n = is.read(buf);
                if(n == -1) {
                    break;
                }
                //此处String的构造是基于前n个字节,而不是整个数组
                String s = new String(buf, 0, n);
                System.out.println(s);
            }
        }
    }
}

运行结果:

 

利用Scanner进行字符读取

上述栗子中,我们看到了对字符类型直接使用InputStream进行读取是非常麻烦且困难的,所以,我们使用一种我们之前比较熟悉的类来完成该工作,就是Scanner类.

构造方法说明
Scanner(InputStream is, String charset)使用charset字符集进行is的扫描读取
import java.io.*;
import java.util.Scanner;

public class FileTest11 {
    public static void main(String[] args) throws IOException {
        try (InputStream is = new FileInputStream("hello-world.txt")) {
            try (Scanner sc = new Scanner(is, "UTF-8")) {
                while (sc.hasNext()) {
                    String s = sc.next();
                    System.out.println(s);
                }
            }
        }
    }
}

OutputStream概述

方法

修饰符及返回值类型方法签名说明
void write(int b)写入要给字节的数据
void write(byte[] b)将b这个字符数组中的数据全部写入os中
intwrite(byte[] b, int off, int len)将b这个字符数组从off开始的数据写入os中,一共写len个
void close()关闭字节流
voidflush()

重要:我们知道I/O的速度是很慢的,所以,大多OutputStream

为了减少设备操作的次数,再写数据的时候都会将数据暂时

写入内存的一个指定区域里,直到该区域满了或者其它指定

条件时才真正将数据写入设备中,这个区域一般称为缓冲区.

但造成一个结果,就是我们写的数据,很可能会遗留一部分在缓冲区中.需要在最后或者合适的位置,调用flush(刷新)操作,

将数据刷新到设备中.

 说明

Output同样只是一个抽象类,要使用还需要具体的实现类.我们现在还是只关心写入文件中,所以使用FileOutputStream.

利用OutputStreamWriter进行字符写入

示例

注意,此处OutputStream默认情况下,会把之前的文件内容都清空掉,然后重新开始写(清空)

不是write引起的,而是打开操作引起的.

写文件的时候,也不是说,非得把文件内容清空,也可以使用追加写的方式,不清空文件内容,把新的内容写到文件末尾.

eg.OutputStream os = new FileOutputStream("test.txt", true);//将后面的append追加视为true即可.

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class FileTest12 {
    public static void main(String[] args) throws IOException {
        try (OutputStream os = new FileOutputStream("hello-world.txt")) {
            os.write('l');
            os.write('b');
            os.write('w');
            os.write('n');
            os.write('b');
            //不要忘记flush
            os.flush();
        }
    }
}
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class FileTest13 {
    public static void main(String[] args) throws IOException {
        try(OutputStream os = new FileOutputStream("hello-world.txt")) {
            byte[] b = new byte[] {
                    (byte)'G', (byte)'o', (byte)'o', (byte)'d'
            };
            os.write(b);
            //不要忘记flush
            os.flush();
        }
    }
}
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class FileTest14 {
    public static void main(String[] args) throws IOException {
        try (OutputStream os = new FileOutputStream("hello-world.txt")) {
            byte[] b = new byte[] {
                    (byte)'b', (byte)'y', (byte)'e'
            };
            os.write(b, 0, 3);

            //不要忘记flush
            os.flush();
        }
    }
}
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class FileTest15 {
    public static void main(String[] args) throws IOException {
        try (OutputStream os = new FileOutputStream("hello-world.txt")) {
            String s = "Nothing";
            byte[] b = s.getBytes();
            os.write(b);

            //不要忘记flush
            os.flush();
        }
    }
}
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class FileTest16 {
    public static void main(String[] args) throws IOException {
        try (OutputStream os = new FileOutputStream("hello-world.txt")) {
            String s = "从今天开始这里叫卢本伟广场";
            byte[] b = s.getBytes("utf-8");
            os.write(b);
            //不要忘记flush
            os.flush();
        }
    }
}

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1403434.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构之使用顺序表写出通讯录

前言 昨天我们踏入了数据结构的深山&#xff0c;并且和顺序表battle了一番&#xff0c;虽说最后赢了&#xff0c;但同时也留下了一个问题&#xff1a;如何从顺序表的增删查改加强到通讯录的的增删查改&#xff0c;别急&#xff0c;今天就带你一探究竟。 一.回顾与思考 我们昨…

二维码地址门牌管理系统:预约安全、智能生活

文章目录 前言一、访客预约功能二、安全性保障三、智慧小区生活 前言 二维码地址门牌管理系统的出现不仅提升了小区的安全性&#xff0c;还为访客提供了更便捷的预约服务&#xff0c;让亲朋好友轻松进入小区。 一、访客预约功能 该系统提供了访客预约功能&#xff0c;业主可为…

【GitHub项目推荐--12306 抢票助手 python】【转载】

这个项目名很干脆&#xff0c;不知道以为是 12306 网站的源码&#xff0c;其实不是这是全 GitHub最德高望重的抢票小助手&#xff0c;功能一直在更新&#xff0c;且现已支持 Python 3.6 以上版本。 开源地址&#xff1a;https://github.com/testerSunshine/12306

安装向量数据库milvus可视化工具attu

使用docker安装的命令和简单就一个命令&#xff1a; docker run -p 8000:3000 -e MILVUS_URL{milvus server IP}:19530 zilliz/attu:v2.3.5sunyuhuasunyuhua-HKF-WXX:~/dockercom/milvus$ docker run -p 8000:3000 -e MILVUS_URL127.0.0.1:19530 zilliz/attu:latest yarn run…

代码随想录 Leetcode1047. 删除字符串中的所有相邻重复项

题目&#xff1a; 代码(首刷自解 2024年1月21日&#xff09;&#xff1a; class Solution { public:string removeDuplicates(string s) {if (s.size() < 2) return s;stack<char> t;for (int i 0; i < s.size(); i) {if (t.empty()) t.push(s[i]);else {if (s[i…

IoC 容器总结

目录 理解 IoC 实现方式 DI 实现原理 Autowired VS Resource 区别 IoC 和 DI 有什么区别 理解 IoC IoC——控制反转&#xff0c;是 Spring 框架的核心概念之一&#xff0c;是一种设计原则和编程模式&#xff0c;用于实现松耦合和可测试的应用程序 控制反转&#xff1a;对…

《二叉树》——1

目录 前言&#xff1a; 二叉树的链式结构 二叉树的遍历 前序遍历&#xff1a; 中序遍历&#xff1a; 后序遍历&#xff1a; 总结&#xff1a; 前言&#xff1a; 从本文开始&#xff0c;将进一步深入学习编程语言思想&#xff0c;从二叉树开始我们将接触许许多多的递归算…

力扣hot100 合并两个有序链表 递归 双指针

Problem: 21. 合并两个有序链表 文章目录 &#x1f496; 递归思路 &#x1f496; 双指针 &#x1f496; 递归 思路 &#x1f468;‍&#x1f3eb; 参考地址 n , m n,m n,m 分别为 list1 和 list2 的元素个数 ⏰ 时间复杂度: O ( n m ) O(nm) O(nm) &#x1f30e; 空间复杂…

力扣62. 不同路径

动态规划 思路&#xff1a; 定义 dp[r][c] 为到达坐标 (r, c) 的路径数&#xff1a; 它只能有同一行左边相邻方格向右到达或者同一列上方相邻方格向下到达&#xff1b;状态转移方程&#xff1a; dp[r][c] dp[r][c - 1] dp[r - 1][c]初始状态 dp[0][0] 1第一行的路径数是 1第…

恒创科技:云服务器配置中的vCPU与物理CPU有啥区别?

​  说到云服务器&#xff0c;您可能经常会遇到vCPU这个词&#xff0c;而且它和物理CPU经常被拿来谈论。尽管它们听起来相似&#xff0c;但两者之间存在显著差异。在本文中&#xff0c;我们将详细讨论云vCPU和物理CPU之间的差异。 物理与虚拟 CPU 和 vCPU 之间最显著的区别在…

【Linux】-对于信号章节补充的知识点,以及多线程知识的汇总

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法&#x1f384; 如 果 你 …

非线性最小二乘问题的数值方法 —— 狗腿法 Powell‘s Dog Leg Method (II, Python 简单实例)

Title: 非线性最小二乘问题的数值方法 —— 狗腿法 Powell‘s Dog Leg Method (II, Python 简单实例) 姊妹博文 非线性最小二乘问题的数值方法 —— 狗腿法 Powell‘s Dog Leg Method (I - 原理与算法) 0.前言 本篇博文作为对前述 “非线性最小二乘问题的数值方法 —— 狗腿法…

L1-069 胎压监测(Java)

小轿车中有一个系统随时监测四个车轮的胎压&#xff0c;如果四轮胎压不是很平衡&#xff0c;则可能对行车造成严重的影响。 让我们把四个车轮 —— 左前轮、右前轮、右后轮、左后轮 —— 顺次编号为 1、2、3、4。本题就请你编写一个监测程序&#xff0c;随时监测四轮的胎压&…

系统架构14 - 软件工程(2)

需求工程 需求工程软件需求两大过程三个层次业务需求(business requirement)用户需求(user requirement)功能需求 (functional requirement)非功能需求 概述活动阶段需求获取基本步骤获取方法 需求分析三大模型数据流图数据字典DD需求定义方法 需求验证需求管理需求基线变更控制…

Hylicos - MINI2440 - 中断控制

中断 中断源管理 中断是一种异步异常&#xff0c;CPU需要处理很多来自设备的中断请求&#xff0c;而CPU引出的line只有IRQ线和FIQ线&#xff0c;所以就得引入中断控制器帮助CPU搞清楚是中断的来源。 MINI2440的中断控制器&#xff0c;可以接受来自60个中断源的请求。提供这些…

Redis双写一致性

所有的情况都是再并发情况下存在温蒂 一、先更新数据库&#xff0c;再更新缓存场景-不推荐 当有两个线程A、B&#xff0c;同时对一条数据进行操作&#xff0c;一开始数据库和redis的数据都为1&#xff0c;当线程A去修改数据库&#xff0c;将1改为2&#xff0c;然后线程A在修改…

幻兽帕鲁专用服务器

随着幻兽帕鲁这款游戏的热度持续升温&#xff0c;我们遍寻全网&#xff0c;带给各位玩家一个全新的、高品质的游戏体验——莱卡云服务器。有幻兽帕鲁的热衷者们无需再为了服务器的选取困扰&#xff0c;因为我们可以肯定地说&#xff1a;选择莱卡云&#xff0c;你不会失望。 首先…

数据库复试—关系数据库标准语言SQL

数据库复试—关系数据库标准语言SQL SQL&#xff1a;结构化查询语言 以教材中的学生-课程数据库为例进行SQL基础语法的复习 数据库实验环境选择SQLServer 11 关系模式 学生表Student(Sno,Sname,Ssex,Sage,Sdept) 课程表Course(Cno,Cname,Cpno,Ccredit) 学生选课表SC&#xf…

Linux操作系统——理解软硬链接

1.引言 通过我们前面理解文件系统的基础上&#xff0c;我们来理解软硬链接&#xff0c;在我们学习文件的时候我们会见到各种链接文件&#xff0c;其中链接文件分为两种&#xff0c;一种叫软连接&#xff0c;一种叫硬链接。 下面我们新建一个log文件&#xff0c;要对log这个文…