【Java文件流】为什么要诞生“字符流”,字节流不是更胜任二进制数据的处理吗?

面试官:字节流可以处理一切文件为什么还需要字符流呢? 输入流:数据流向程序输出流:数据从程序流出。字节流:一次读入或读出是8位二进制;字符流:一次读入或读出是16位二进制JDK 中后缀是 Stream 是字节流;后缀是 Reader,Writer 是字符流。节点流:直接与数据源相连,读入或写出;处理流:与节点流一块使用,在节点流的基础上,再套接一层。 阅读详情

根本原因是由于人和机器的差距:机器擅长处理二进制的机器码,而人只能处理特殊的字符(如"a",“你好”)。于是,采用字符流来作为人能读的文件与机器能读的文件之间的转换桥梁。

诞生背景:

  • 字节流对所有的文件操作都是按照一个个二进制位的形式;
  • 然而,字节流在操作字符时,可能会有中文导致的乱码,所以由字节流引申出了字符流。

为什么要诞生字符流:

  • 机器擅长处理二进制的机器码,而人只能处理特殊的字符(如"a",“你好”)。
  • 于是,采用字符流来作为人能读的文件与机器能读的文件之间的转换桥梁。

字符流的功能:

  1. 把读取到的二进制数据进行对应的编码和解码工作;从而把二进制位转换成程序员期待的字符集。
  2. 字符流=字节流+编码(解码);

字符流的弊端:

  • 一:无法拷贝图片和视频。
  • 二:拷贝文件使用字节流而不使用字符流,因为字符流读文件涉及到解码,会先解码,写文件的时候又涉及到编码,这些操作多余,而且读和写的码表不对应还容易引发问题。
  • 例如FileReader 读文件,我们没有指定编码时,默认是按照系统编码gbk进行操作,如果读到utf-8的文件也是按照gbk编码进行解码,那就会出现问题。

字符流体系结构

输入字符流:
---------| Reader 所有输入字符流的基类。 抽象类。
----------------| FileReader 读取文件数据的输入字符流。
----------------|BufferedReader 缓冲输入字符流。该类出现的目的是为了提高读取文件数据的效率与拓展FileReader的(readLine)功能。这个类的也只不过是在内部维护了一个8kb的字符数组而已。

输出字符流:
---------| Writer 所有输出字符流的基类。 抽象类
----------------| FileWriter 向文件输出数据的输出字符流
----------------| BufferedWriter 缓冲输出字符流。该类出现的目的是为了提高写文件数据的效率与拓展FileWriter的(newLine)功能。

FileReader

在这里插入图片描述

FileReader类操作步骤、方法与FileInputStream类相同;缓冲流的使用方法与FileInputStream类相同,即bufferedReader包装FileReader

读取方法:
1,int read():一次读取一个字符。返回的是读到的那个字符的int值。如果读到流的末尾,返回-1.
2,int read(char[]):将
读到的字符存入指定的数组中
,返回的是读到的字符个数,也就是往数组里装的元素的个数。如果读到流的末尾,返回-1.

快速理解FileReader的用法:

import java.io.IOException;
import java.io.FileReader;

public class Main {
	public static void main(String[] args) throws IOException {
		readOneCharacter(); //读取一个字符
		readCharacterArray(); //读取一个字符数组
	}

	public static void readOneCharacter() throws IOException {
		FileReader fr = new FileReader("c:\\users\\kyles\\desktop\\a.txt");
		int ch;
		while((ch=fr.read())!=-1) {
			System.out.print((char)ch);
		}
		fr.close();
	}
	public static void readCharacterArray() throws IOException {
		FileReader fr = new FileReader("c:\\users\\kyles\\desktop\\a.txt");
		char[] chs = new char[1024]; //这里可以是1024及其整数倍
		int len;
		while((len=fr.read(chs))!=-1) {
			System.out.print(new String(chs,0,len));
		}
		fr.close();
	}
}

FileWriter

在这里插入图片描述

使用FileWriter写数据的时候

  1. FileWriter内部是维护了一个1024个字符数组的,写数据的时候会先写入到它内部维护的字符数组中,如果需要把数据真正写到硬盘上,需要调用flush或者是close方法或者是填满了内部的字符数组。
  2. 如果目标文件不存在,那么会自动创建目标文件。
  3. 如果目标文件已经存在了,那么默认情况会先清空文件中的数据,然后再写入数据。

向磁盘文件写数据的五种方法:(五种write方法的重载)

public void write(int c) throws IOException  写入的字符包含在给定整数值的16个低位中; 忽略16个高位。
public void write(char[] cbuf) throws IOException
public abstract void write(char[] cbuf, int off, int len) throws IOException
public void write(String str) throws IOException
public void write(String str, int off, int len) throws IOException

向一个文件中写入一个字符串

import java.io.FileWriter;
import java.io.IOException;

public class Main {
	public static void main(String[] args) throws IOException { //为了快速理解,异常直接向函数外抛
		FileWriter fw = new FileWriter("C:\\users\\kyles\\desktop\\a.txt");
		fw.write("IO流你好"); //数据没有直接写到文件,其实是写到了内存缓冲区
		
		fw.flush(); //把缓冲区的数据写入到文件
		fw.close(); //先刷新缓冲区,然后通知系统释放资源。
	}
}

五种write方法示例

import java.io.FileWriter;
import java.io.IOException;
public class Main {
	public static void main(String[] args) throws IOException {
		//创建输出流对象
		FileWriter fw = new FileWriter("b.txt");
		
		//void write(String str):写一个字符串数据
		fw.write("abcde");
		
		//void write(String str,int index,int len):写一个字符串中的一部分数据
		fw.write("abcde",0,5);
		fw.write("abcde",1,3);
		
		//void write(int ch):写一个字符数据,这里写int类型的好处是既可以写char类型的数据,也可以写char对应的int类型的值。'a',97
		fw.write('a');
		fw.write(97);
		
		//void write(char[] chs):写一个字符数组数据
		char[] chs = {'a','b','c','d','e'};
		fw.write(chs);
		
		//void write(char[] chs,int index,int len):写一个字符数组的一部分数据
		fw.write(chs,0,5);
		fw.write(chs,2,3);
		
		//释放资源
		fw.close();
	}
}

文件追加

  • 在构造函数时就设置为追加模式:
FileWriter(String fileName, boolean append) 
FileWriter fw = new FileWriter("c.txt",true); //表示追加写入,默认是false
FileWriter(File file, boolean append)
  • 使用append方法
Writer append(char c); //将制定字符添加到此Writer
Writer append(CharSequence csq); //将制定字符序列添加到此Writer
Writer append(CharSequence csq, int start, int end);

示例:

import java.io.FileWriter;
import java.io.IOException;
public class Main {
	public static void main(String[] args) throws IOException {
		FileWriter fw = new FileWriter("c:\\users\\kyles\\desktop\\a.txt");
		for(int x=0; x<10; x++) {
			fw.write("hello"+x);
			fw.write("\r\n");
		}
		fw.close();
	}
}

关于换行符

\n可以实现换行,但是windows系统自带的记事本打开并没有换行,这是为什么呢?——因为windows识别的换行不是\n,而是\r\n

  • windows:\r\n
  • linux:\n
  • mac:\r

字符缓冲流

Reader有一个子类BufferedReader。子类继承父类显然子类可以重写父类的方法,也可以增加自己的新方法。例如一次读一行就是常用的操作。那么BufferedReader 类就提供了这个方法,可以查看readLine()方法具备 一次读取一个文本行的功能。很显然,该子类可以对功能进行增强。

两类字符缓冲流:
在这里插入图片描述 在这里插入图片描述

缓冲流的特殊功能(特殊方法):

  • BufferedWriter
    void newLine():写一个换行符,这个换行符由系统决定
  • BufferedReader
    String readLine():一次读取一行数据,但是不读取换行

缓冲流使用示例

import java.io.IOException;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.BufferedWriter;

public class Main {
	public static void main(String[] args) throws IOException {
		Wr();
		Re();
	}

	public static void Wr() throws IOException {
		File path = new File("c:\\users\\kyle\\desktop\\a.txt");
		FileWriter fw = new FileWriter(path);
		BufferedWriter bw = new BufferedWriter(fw);
		for(int i=0;i<10;i++) {
			bw.write(i + ": hello");
			bw.newLine();//相当于:bw.write("\r\n");
			bw.flush();
		}
		bw.close();
	}
	public static void Re() throws IOException {
		File path = new File("c:\\users\\kyle\\desktop\\a.txt");
		FileReader fr = new FileReader(path);
		BufferedReader br = new BufferedReader(fr);
		String line;
		while((line = br.readLine())!=null) {
			System.out.println(line);
		}
		fr.close();
	}
}
RK3588 Weston 下面是使用 weston -B=vnc-backend.so --width=1280 --height=720 ,使用vnc的客户端来远程访问weston桌面。Wayland是一套display server(Wayland compositor)与client间的。,而Weston是Wayland compositor的参考实现。7:在基于wayland 运行Qt 程序。根据不同版本,支持的后端也不相同。2:当前weston支持的后端。4:weston的配置文件。3:weston中的录屏。 阅读详情

相关推荐

OpenStack 8 节点生产级高可用(HA)集群实施文档

本文详细介绍了生产级高可用OpenStack集群的架构设计与实施方案。通过采用3节点控制集群(HAProxy+Keepalived)、2节点计算资源池和3节点Ceph分布式存储,实现了控制平面、计算资源和存储系统三个层面的高可用。方案重点阐述了VIP漂移、MariaDB Galera集群、RabbitMQ镜像队列等关键组件的配置方法,并提供了完整的部署流程和故障验证方案。该架构确保任意单节点故障不会影响平台整体可用性,满足生产环境对稳定性、扩展性和可维护性的要求,为构建无单点故障的OpenStack生产环境

彭大帅的博客 780

什么是字符流?为什么会有字符流?

为什么出现字符流?因为字节流操作中文不是特别方便,所以Java就提供字符流;字符流=字节流+编码表;字节流复制文本文件时也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文,如何识别中文呢?是因为汉字在存储时无论选择哪种编码存储,第一个字节都是负数。 ...

wangkexiang21的博客 2802

中兴FTTR光猫变简易OLT:低成本搭建全光监控与局域网实战指南

本文详细介绍了如何将中兴FTTR光猫改造为简易OLT设备,实现低成本全光监控与局域网扩展。通过LOID认证、桥接模式设置及终端数破解,用户可利用二手设备搭建高性能光纤网络,适用于远程监控和长距离组网场景,显著降低部署成本。

chair的专栏 2026

java中明明已经有了字节流,为什么还要设置一个字符流

因为字节流在传输字符流的时候,是不管你是不是字符或者什么的,就只传输二进制序列,那么当你传输完后,想要识别这些序列的时候,就会需要再重新解码,而且在解码的时候,可能会出现编码错误。首先,字符流是根据一个字符一个字符进行传输的,默认是utf-8,也就是说,只有当识别二进制代码判断出是一个字符的时候,就会传输,但是并不是所有二进制代码序列都有对应的字符,即无法识别的二进制序列,这个时候会默认将此段二进制序列更改为默认的二进制序列,而不再是原来的真实的序列了。那么字符流能做到的,字节流都能做到。

weixin_42761614的博客 777

Python、Selenium实现问卷星自动填写(内含适配个人问卷的方法)

使用Python、Selenium实现问卷星自动填写,内含适配个人问卷的方法。

DaenCode的博客 3836

【YOLOv10[基础]】热力图可视化实践③ | 热力图脚本升级 | 优化可视化效果 | 论文必备 | GradCAMPlusPlus, GradCAM, XGradCAM, EigenCAM等

热力图可视化实践③ | 热力图脚本升级 | 优化可视化效果 | 论文必备 | 遥遥领先

静谧、淡雅 3220

既然有了字节流,为什么还要有字符流?

因为字节流转换成字符流,过程很耗时。如果你必须要使用字符流,但你只得到了字节流,就要经历这个转换,其中编码也容易出问题。所以就直接把字符流单独作为了一个部分,从而提高使用字符流的效率。 ...

di_ko的博客 2938

图神经网络实战(1)——图神经网络(Graph Neural Networks, GNN)基础

本节全面介绍了图神经网络 (Graph Neural Network, GNN) ,包括其在数据分析和机器学习中的重要性。首先探讨了图作为数据表示的相关概念及其在各个领域的广泛应用;然后深入探讨图学习的重要性,包括不同的应用和技术。最后,重点介绍了 GNN 架构,并对比了它与其他方法之间的原理和性能差异。

盼小辉丶的博客 15万+

Java中字节流和字符流的区别

Java中字节流与字符流的区别

qq_53756844的博客 1044

ESP32设备驱动-AS5600磁性旋转位置传感器

AS5600 是一款可编程的 12 位高分辨率非接触式磁性旋转位置传感器。 AS5600可以作为磁性电位器或磁性编码器使用,具有出色的可靠性和耐用性。 与传统电位器/编码器相比,AS5600具有显着优势:高精度、非接触式、旋转角度无限制。 所有这些优点使其适用于非接触式角度测量应用,例如机器人手臂、云台、电机闭环控制、机床轴定位。

视觉与物联智能 2550

拉曼光谱入门:10.显微拉曼与共聚焦技术

本文系统阐述了显微拉曼光谱技术与共聚焦原理的融合机制,详细解析了从激光激发、针孔空间滤波到光谱采集的完整光路架构,阐明了共聚焦设计在提升三维空间分辨率、抑制荧光背景及实现微区无损层析方面的核心优势,并探讨了关键光学器件的性能边界与系统技术局限。

qq_53529450的博客 166

字节流和字符流详解

1.流的概念 在编程中是一种抽象的概念,就好比“水流”,从一段流向另一端 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成。 程序中的输入输出都是以流的形式保存的,流中保存的实际上全都是字节文件。 2.流的分类 按照流向可以分为:输入流(如:键盘,麦克风),输出流(如:显示器,音箱) 按照传输单位可以分为:字节流和字符流 3.什么是字节流,什么是字符流 字节流: 它处理单元为1个字节(byte),操作字节和

wkh18891843165的博客 3万+

【图论】系列(七)图论的中心性度量方法及重要性评价指标

图论中的中心性度量方法是用来衡量图中各个节点(或顶点)相对重要性的指标。

qq_30066733的博客 1075

字符流与字节流的区别

字符流与字节流的区别 (尊重劳动成果,转载请注明出处:https://blog.youkuaiyun.com/cynhafa/article/details/6882061陈江玉的博客) 字节流与和字符流的使用非常相似,两者除了操作代码上的不同之外,是否还有其他的不同呢? 实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作文件,如图12-6所示...

Wangz的博客 6万+

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Java 字节流与字符流的区别详解

原文地址:https://www.cnblogs.com/DONGb/p/7844123.html 1. 流的概念 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成。 程序中的输入输出都是以流的形式保存的,流中保存的实际上全都是字节文件。 2. 字节流与字符流 在java.io包中操作文件内...

学习笔记 1万+

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

【Java】IO流:字节流 字符流 缓冲流

流”是一个抽象的概念,是对输入输出设备的一种抽象理解,在Java中,对数据的输入输出都是以“流”的的方式进行的。这个例子中,小推车可以视为缓冲区,小推车的存在,减少了我们装车次数,从而提高了效率。这是因为我们在创建流后,在流使用后,需要对流进行关闭,在写入到try后面的小括号内时,我们就可以不必手动的来进行流的关闭,减少一些情况下我们忘记关闭流这一操作带来的风险,字符流:数据流中的最小的数据单元是字符,一次读入读出16位二进制,java中的字符是Unicode编码,一个字符占用两个字节。

daydayup 2299

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

字节流和字符流

在Java.io包中操作文件内容主要有两大类:字节流和字符流,两类都分为输入输出操作。所有文件的存储都是按字节(byte)来存储的,在磁盘上保留的并不是文件的字符而是把字符编码成字节,再存储这些字节到磁盘。在读取文件(特别是文本文件)时,也是一个字节一个字节的读取以形成字节序列。

qq_59808309的博客 2392

Java字节流和字符流,是时候总结一下IO流了

字节流和字符流:为什么字符流需要 flush

zwx900102的博客 2689

java中字节流,字符流

提供了read()方法来逐个字节地读取数据。这个方法返回一个int值,范围是 0 - 255,表示读取到的字节数据(该方法一次读取一个字符并以整数格式返回其ASCII值),需要转为char类型,当返回 - 1 时,表示已经到达流的末尾。如果读取的文件中含有汉字,会产生乱码。utf8汉字有3个字节,但是read()方法一次只能读取一个字节,无法正常读取在这里会产生异常,可以使用throws IOException 或者try catch finally抛出,最好使用后者。

weixin_72976692的博客 1159

字节(byte)、二进制、字节流、字符流相关概念分析

1.字节:     字(Byte)节是长度单位。位(bit)也是长度单位。 因为计算机通信和存储的时候都是以010101这样的二进制数据为基础的,这儿的一个0和1占的地方就叫bit(位),即一个二进制位。 1Byte=8bit 1KB=1024B 1MB=1024KB(2的十次方) 2.二进制  二进制数有两个特点:它由两个基本字符0,1组成,二进制数运算规律是逢二进一。  为区别

changwilling的博客 2万+

java 字节流与字符流的区别

字节流是通用的,可以处理所有类型的数据,尤其是二进制数据。字符流主要用于文本数据,它会自动处理字符编码,简化了字符数据的读取和写入。根据实际情况选择合适的流类型,可以帮助你更高效地进行 I/O 操作。

heromps的博客 1077

Java的IO流 - 字节流和字符流

在Java中,IO流(Input/Output Stream) 是进行数据输入与输出处理的基础机制,广泛应用于文件读写、网络通信、序列化等场景。IO流体系庞大,但本质可分为两大类:字节流和字符流。本文将围绕这两个核心概念,系统讲解其原理、使用方法和适用场景,帮助读者深入理解Java的IO流机制。

weixin_73144915的博客 1550

java http 传输二进制流_字符流、字节流、二进制及其在HTTP协议传输

一、二进制、字节、字符流概念字(Byte)节是长度单位。位(bit)也是长度单位。计算机通信和存储的时候都是以010101这样的二进制数据为基础的二进制数有两个特点:它由两个基本字符0,1组成,二进制数运算规律是逢二进一。在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成。程序中的输入输出都是以流的形式...

weixin_39761647的博客 4374

java中字符流和字节流的区别_java中字节流和字符流有哪些区别

java中字节流和字符流的区别有:1、定义不同;2、结尾不同;3、处理方式不同;4、缓冲区不同;5、编码方式不同。字节流默认不使用缓冲区,而字符流使用缓冲区。字节流采用ASCII编码,字符流采用unicode编码。流是一系列随时间而可用的数据;源将数据生成为流,目标消耗或读取数据可用作流。换句话说,流解释了允许读或写的数据流。在Java中执行流操作的两种方式是使用字节流和字符流。下面我们就来简单了...

weixin_42699679的博客 6434
上一篇: 【Java文件流】我尝试用一文把“字节流”说清楚
下一篇: 【Java文件流】简单明了的“编码”教程
ALGO阿狗
博客等级 码龄9年 64粉丝 149原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值