文件操作与IO(3)

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

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

之前也在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();
        }
    }
}

 

 

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

20240122让WIN10在启动的时候进入安全模式

20240122让WIN10在启动的时候进入安全模式 2024/1/22 18:30 缘起&#xff1a;为了使用openai的whisper识别小语种【非英语】电影的字幕&#xff0c;决定开始折腾CUDA了&#xff01;https://github.com/openai/whisper https://www.bilibili.com/video/BV1d34y1F7qA https://www…

API协议设计的十种技术

文章目录 前言一、REST二、GraphQL三、gRPC&#xff08;google Remote Procedure Calls&#xff09;四、Webhooks五、服务端的事件发送——SSE&#xff08;Server-sent Events&#xff09;六、EDI&#xff08;Electronic Data Interchange&#xff09;七、面向API 的事件驱动设…

HarmonyOS NEXT 开发者必看“清单“就在这里!

随着HarmonyOS NEXT开启开发者预览版Beta招募&#xff0c;开发者可以体验到全面升级的 OS开放新能力、鸿蒙特征新场景、开发工具等。这是一项需要广大开发者一起参与的伟大事业&#xff0c;华为期待携手开发者一路同行&#xff0c;共赴鸿蒙生态的星辰大海。如何借助HarmonyOS N…

数据集笔记:UJIIndoorLoc

1 数据集介绍 UJIIndoorLoc - UCI Machine Learning Repository UJIIndoorLoc是一个多建筑多楼层的室内定位数据库&#xff0c;用于测试依赖于WLAN/WiFi指纹的室内定位系统。 2 数据读取 数据分类训练数据和测试数据 import pandas as pdapd.read_csv(Downloads/ujiindoo…

矩阵和矩阵如何相乘?

矩阵与矩阵相乘遵循特定的数学规则。为了相乘&#xff0c;第一个矩阵的列数必须等于第二个矩阵的行数。矩阵乘法的结果是一个新矩阵&#xff0c;其行数等于第一个矩阵的行数&#xff0c;列数等于第二个矩阵的列数。矩阵乘法不满足交换律&#xff0c;即 AB≠BA。 例子&#xff…

MySQL---多表分组查询综合练习

创建dept表 CREATE TABLE dept ( deptno INT(2) NOT NULL COMMENT 部门编号, dname VARCHAR (15) COMMENT 部门名称, loc VARCHAR (20) COMMENT 地理位置 ); 添加dept表主键 mysql> alter table dept add primary key(deptno); Query OK, 0 rows affected (0.02 s…

Mybatis 动态SQL条件查询(注释和XML方式都有)

需求 : 根据用户的输入情况进行条件查询 新建了一个 userInfo2Mapper 接口,然后写下如下代码,声明 selectByCondition 这个方法 package com.example.mybatisdemo.mapper; import com.example.mybatisdemo.model.UserInfo; import org.apache.ibatis.annotations.*; import j…

接口测试介绍以及用例编写

6.1 接口 6.1.1 接口概述 定义&#xff1a; 接口就是API&#xff08;Application Programming Interface&#xff0c;应用程序接口&#xff09;&#xff0c;是一个软件或服务对外提供的接口&#xff0c;别人只要调用这接口&#xff0c;而内部如何实现&#xff0c;不需要关心。…

Python 算法交易实验67 第一次迭代总结

说明 在这里对第一次迭代&#xff08;2023.7~ 2024.1&#xff09;进行一些回顾和总结&#xff1a; 回顾&#xff1a; 1 实现了0~1的变化2 在信息隔绝的条件下&#xff0c;无控制的操作&#xff0c;导致被套 总结&#xff1a; 思路可行&#xff0c;在春暖花开的时候&#x…

3分钟带你了解,软件测试是做什么的

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

springboot集成COS对象存储

1.申请腾讯云存储桶 新建密钥&#xff08;后面配置要用到&#xff09; 2.编写工具类 此处使用工具类进行基本属性配置&#xff0c;也可选择在yml中配置 package com.sfy.util;import com.qcloud.cos.COSClient; import com.qcloud.cos.ClientConfig; import com.qcloud.cos.a…

【网络安全 -> 防御与保护】专栏文章索引

为了方便 快速定位 和 便于文章间的相互引用等 作为一个快速准确的导航工具 网络安全——防御与保护 &#xff08;一&#xff09;.信息安全概述

地图 - 实现有多条定位,显示多条定位,并且使用一个圆形遮罩层将多条定位进行覆盖

首先&#xff0c;需要在你的index.html模板页面头部加载百度地图JavaScript API代码&#xff0c;密钥可去百度地图开放平台官网申请 <script type"text/javascript" src"//api.map.baidu.com/api?typewebgl&v1.0&ak您的密钥"></script&…

消息队列之王——Kafka

Zookeeper 在学习kafka之前&#xff0c;我们需要先学习Zookeeper&#xff0c;那Zookeeper是什么呢&#xff1f;Zookeeper是一个开源的分布式的&#xff0c;为分布式框架提供协调服务的Apache项目。 Zookeeper 工作机制 Zookeeper从设计模式角度来理解&#xff1a;是一个基于观…

VUE---插槽

一、插槽的作用&场景 1、在封装组件的时候&#xff0c;将可变的结构设计为插槽&#xff08;<slot></slot>&#xff09; 2、使用上述组件的时候&#xff0c;可以按需为插槽提供自定义的结构&#xff0c;以达到复用组件且高度自定的效果 二、基本语法 1、组件内…

2024年【广东省安全员B证第四批(项目负责人)】新版试题及广东省安全员B证第四批(项目负责人)作业模拟考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 广东省安全员B证第四批&#xff08;项目负责人&#xff09;新版试题参考答案及广东省安全员B证第四批&#xff08;项目负责人&#xff09;考试试题解析是安全生产模拟考试一点通题库老师及广东省安全员B证第四批&…

在CentOS 7中配置 RAID服务

实验过程 Xnode1克隆虚拟机raid ps&#xff1a; 阿里云盘Xnode1获取 xnode1 https://www.alipan.com/s/HgLXfoeBWG2 提取码: eb70 编辑虚拟机 添加2硬盘 CRT连接&#xff08;root密码&#xff1a;000000&#xff09; 创建raid 0 [rootdemo ~]# lsblk 安装mdadm [rootdemo…

Facebook直播指南:教你如何轻松控评

Facebook直播在促进互动、扩大影响力、实时报道、创造内容和商业机会等方面都可以发挥很好的效果。无论是企业推广产品还是个人博主提升人气&#xff0c;Facebook直播都是一个值得尝试的渠道。 但是在刚开始直播的时候&#xff0c;可能会遇到以下情况&#xff1a;想要通过Face…

Java项目:ssm框架基于spring+springmvc+mybatis框架的民宿预订管理系统设计与实现(ssm+B/S架构+源码+数据库+毕业论文)

一、项目简介 本项目是一套ssm827基于SSM框架的民宿预订管理系统设计与实现&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调…

【数据结构与算法】之字符串系列-20240122

这里写目录标题 一、383. 赎金信二、387. 字符串中的第一个唯一字符三、389. 找不同四、392. 判断子序列五、409. 最长回文串 一、383. 赎金信 简单 给你两个字符串&#xff1a;ransomNote 和 magazine &#xff0c;判断 ransomNote 能不能由 magazine 里面的字符构成。 如果…