【Java EE】文件内容的读写——数据流

news/2024/9/22 18:12:12/

目录

1.InputStream概述

1.1方法

2.FileInputStream概述

2.1构造方法

2.2代码示例

2.3.利用Scanner进行字符读取

3.OutputStream概述

3.1方法

3.2利用OutputStreamWriter进行字符写入

3.3利用PrintWriter找到我们熟悉的方法


1.InputStream概述

1.1方法
修饰符及返回值类型方法签名说明
intread()读取一个字节的数据,返回-1代表已经完全读完了。
intread(byte [] b)最多读取b.length字节的数据到b中,返回实际读取到的数量;-1代表以及读完了
int

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

最多读取len-off字节的数据到b中,放在off开始,返回实际读取到的数量;-1代表以及读取完了
voidclose()关闭字节流

说明

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

2.FileInputStream概述

2.1构造方法
签名说明
FileInputStream(File file)利用File构造文件输入流
FileInputStream(String name)利用文件路径构造文件输入流
2.2代码示例

示例1

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

java">import java.io.*;
// 需要先在项⽬⽬录下准备好⼀个 hello.txt 的⽂件,⾥⾯填充 "Hello" 的内容
public class Main {public static void main(String[] args) throws IOException {try (InputStream is = new FileInputStream("hello.txt")) {while (true) {int b = is.read();if (b == -1) {// 代表⽂件已经全部读完break;}System.out.printf("%c", b);}}}
}
java">import java.io.*;
// 需要先在项⽬⽬录下准备好⼀个 hello.txt 的⽂件,⾥⾯填充 "Hello" 的内容
public class Main {public static void main(String[] args) throws IOException {try (InputStream is = new FileInputStream("hello.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.txt中填写“你好中国”

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

java">import java.io.*;
// 需要先在项⽬⽬录下准备好⼀个 hello.txt 的⽂件,⾥⾯填充 "你好中国" 的内容
public class Main {public static void main(String[] args) throws IOException {try (InputStream is = new FileInputStream("hello.txt")) {byte[] buf = new byte[1024];int len;while (true) {len = is.read(buf);if (len == -1) {// 代表⽂件已经全部读完break;}// 每次使⽤ 3 字节进⾏ utf-8 解码,得到中⽂字符// 利⽤ String 中的构造⽅法完成// 这个⽅法了解下即可,不是通⽤的解决办法for (int i = 0; i < len; i += 3) {String s = new String(buf, i, 3, "UTF-8");System.out.printf("%s", s);}}
}
}
}
2.3.利用Scanner进行字符读取

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

构造方法说明
Scanner(InputStream is, String charset)使用charset字符集进行is的扫描读取

示例1

java">import java.io.*;
import java.util.*;
// 需要先在项⽬⽬录下准备好⼀个 hello.txt 的⽂件,⾥⾯填充 "你好中国" 的内容
public class Main {public static void main(String[] args) throws IOException {try (InputStream is = new FileInputStream("hello.txt")) {try (Scanner scanner = new Scanner(is, "UTF-8")) {while (scanner.hasNext()) {String s = scanner.next();System.out.print(s);}}}}
}

3.OutputStream概述

3.1方法
修饰符及返回值类型方法签名说明
voidwrite(int b)写入要给字节的数据
voidwrite(byte [] b)将b这个字符数组中的数据全部写入os中
intwrite(byte[] b,int off,int len)将b这个字符数组中从off开始的数据写入os中,一共写len个
voidclose()关闭字节流
voidflush()重要:我们知道I/O的速度是很慢的,所以,大多的OutPutStream为了减少设备操作的次数,在写数据的时候会将数据先暂时写入内存的一个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写入设备中,这个区域一般称为缓冲区。但造成一个结果,就是我们写的数据,但可能会遗留一部分在缓冲区中。需要在最后或者合适的位置,调用flush(刷新)操作,将数据刷到设备中。

说明

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

3.2利用OutputStreamWriter进行字符写入

示例1

java">import java.io.*;
public class Main {public static void main(String[] args) throws IOException {try (OutputStream os = new FileOutputStream("output.txt")) {os.write('H');os.write('e');os.write('l');os.write('l');os.write('o');// 不要忘记 flushos.flush();}}
}
java">import java.io.*;
public class Main {public static void main(String[] args) throws IOException {try (OutputStream os = new FileOutputStream("output.txt")) {byte[] b = new byte[] {(byte)'G', (byte)'o', (byte)'o', (byte)'d'};os.write(b);// 不要忘记 flushos.flush();}}
}
java">import java.io.*;
public class Main {public static void main(String[] args) throws IOException {try (OutputStream os = new FileOutputStream("output.txt")) {byte[] b = new byte[] {(byte)'G', (byte)'o', (byte)'o', (byte)'d', (byte)'B', (byte)'a'};os.write(b, 0, 4);// 不要忘记 flushos.flush();}}
}
java">import java.io.*;
public class Main {public static void main(String[] args) throws IOException {try (OutputStream os = new FileOutputStream("output.txt")) {String s = "Nothing";byte[] b = s.getBytes();os.write(b);// 不要忘记 flushos.flush();
}
}
}
java">import java.io.*;
public class Main {public static void main(String[] args) throws IOException {try (OutputStream os = new FileOutputStream("output.txt")) {String s = "你好中国";byte[] b = s.getBytes("utf-8");os.write(b);// 不要忘记 flushos.flush();}}
}
3.3利用PrintWriter找到我们熟悉的方法

上述,我们其实已经完成输出工作,但总是有所不方便,我们接下来将OutputStream处理下,使用PrintWriter类中完成输出,因为 PrintWriter类中提供了我们熟悉的print/println/printf方法

java">outputStream os = ...;
OutputStreamWriter osWriter = new OutputStreamWriter(os, "utf-8"); // 告诉
PrintWriter writer = new PrintWriter(osWriter);
// 接下来我们就可以⽅便的使⽤ writer 提供的各种⽅法了
writer.print("Hello");
writer.println("你好");
writer.printf("%d: %s\n", 1, "没什么");
// 不要忘记 flush
writer.flush();

示例1

java">import java.io.*;
public class Main {public static void main(String[] args) throws IOException {try (OutputStream os = new FileOutputStream("output.txt")) {try (OutputStreamWriter osWriter = new OutputStreamWriter(os, "UTF-8try (PrintWriter writer = new PrintWriter(osWriter)) {writer.println("我是第⼀⾏");writer.print("我的第⼆⾏\r\n");writer.printf("%d: 我的第三⾏\r\n", 1 + 1);writer.flush();}}}}
}

http://www.ppmy.cn/news/1428557.html

相关文章

第20天:信息打点-红蓝队自动化项目资产侦察企查产权武器库部署网络空间

第二十天 一、工具项目-红蓝队&自动化部署 自动化-武器库部署-F8x 项目地址&#xff1a;https://github.com/ffffffff0x/f8x 介绍&#xff1a;一款红/蓝队环境自动化部署工具,支持多种场景,渗透,开发,代理环境,服务可选项等.下载&#xff1a;wget -O f8x https://f8x.io…

开发语言漫谈-rust

前面介绍C语言家族时忘掉了rust&#xff0c;紧急补一篇。我们称C语言家族是指他们的语法相似&#xff0c;类似这样的&#xff1a; if(){}else{}就是C家族的。C、C的传统领域就是系统底层、硬件接口方向。C/C没有垃圾内存回收机制&#xff0c;完全靠程序员的自觉天赋&#xff0…

IDEA gradle新增依赖报Could not resolve symbol “XXX“错误

问题 idea 新增依赖后一直报错Could not resolve symbol “XXX”&#xff0c;无法成功下载依赖 原因 未知 解决方案 暂时的解决方案是使用控制台输命令编译&#xff0c;成功编译后依赖也下载下来了&#xff0c;猜测应该是idea的问题&#xff0c;先记录下&#xff0c;后续找…

【java、微服务】MQ

同步通讯 优点 时效性较强&#xff0c;可以立即得到结果 问题 微服务间基于Feign的调用就属于同步方式&#xff0c;存在一些问题。 耦合度高。每次加入新的需求&#xff0c;都要修改原来的代码资源浪费。调用链中的每个服务在等待响应过程中&#xff0c;不能释放请求占用的…

Spring-dataSource事务案例分析-使用事务嵌套时,一个我们容易忽略的地方

场景如下&#xff1a; A_Bean 中的方法a()中调用B_Bean的b();方法都开启了事务&#xff0c;使用的默认的事务传递机制&#xff08;即&#xff1a;属于同一事务&#xff09;&#xff1b; 如下两种场景会存在较大的差异&#xff1a; 在b()方法中出现了异常&#xff0c;在b()中进…

【题解】NC40链表相加(二)(链表 + 高精度加法)

https://www.nowcoder.com/practice/c56f6c70fb3f4849bc56e33ff2a50b6b?tpId196&tqId37147&ru/exam/oj class Solution {public:// 逆序链表ListNode* reverse(ListNode* head) {// 创建一个新节点作为逆序后链表的头节点ListNode* newHead new ListNode(0);// 当前…

【高阶数据结构】并查集 -- 详解

一、并查集的原理 1、并查集的本质和概念 &#xff08;1&#xff09;本质 并查集的本质&#xff1a;森林。 &#xff08;2&#xff09;概念 在一些应用问题中&#xff0c;需要将 n 个不同的元素划分成一些不相交的集合。 开始时&#xff0c;每个元素自成一个单元素集合&…

C++修炼之路之list--C++中的双向循环链表

目录 前言 一&#xff1a;正式之前先回顾数据结构中的双向循环链表 二&#xff1a;list的简介 三&#xff1a;STL中list常用接口函数的介绍及使用 1.构造函数接口 2.list迭代器 范围for 3.数据的修改接口函数 4.list容量操作函数 5.list的迭代器失效 6.演示代码和测…