1.Java 中的IO的作用

IO指的是Input和Output,主要目的是实现数据在存储介质之间的传输。【流:数据流,类比与水流的流动】

2.IO分类

按照操作单元来划分,可以分为字节流和字符流。

3.字节流和字符流的区别

字节流顾名思义操作的数据单元是1个字节,也就是8位;

那么问题来了,一个中文字符用GBK编码占用两个字节,用UTF-8占用三个字符。

字节流在传输有中文字符的数据时会产生编码错误。

而字符流可操作2个字节,也就是16位。那么在GBK的编码下,支持中文数据传输。

总结如下

  • 字节流一次读取一个字节,字符流两个
  • 字节流可以处理所有类型数据,字符流只能处理字符类数据

4.字符编码的前世今生

ASCII 码

计算机内部,所有信息最终都是一个二进制值。每一个二进制位(bit)有01两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte)。

也就是说,一个字节一共可以用来表示256种不同的状态,每一个状态对应一个符号,就是256个符号,从0000000011111111

上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为 ASCII 码,一直沿用至今。

【ASCII 码==英文字符和二进制之间的映射关系】

Unicode

世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。电子邮件常常出现乱码就是因为发信人和收信人使用的编码方式不一样。

可以想象,如果有一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,那么乱码问题就会消失。这就是 Unicode,就像它的名字都表示的,这是一种所有符号的编码。

Unicode 当然是一个很大的集合,现在的规模可以容纳100多万个符号。每个符号的编码都不一样,比如,U+0639表示阿拉伯字母AinU+0041表示英语的大写字母AU+4E25表示汉字。具体的符号对应表,可以查询unicode.org,或者专门的汉字对应表

Unicode 的问题

Unicode虽然实现了编码的一统,但Unicode 只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。

比如,汉字的 Unicode 是十六进制数4E25,转换成二进制数足足有15位(100111000100101),也就是说,这个符号的表示至少需要2个字节。表示其他更大的符号,可能需要3个字节或者4个字节,甚至更多。

这里就有两个严重的问题,第一个问题是,如何才能区别 Unicode 和 ASCII ?计算机怎么知道三个字节表示一个符号,而不是分别表示三个符号呢?第二个问题是,我们已经知道,英文字母只用一个字节表示就够了,如果 Unicode 统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储来说是极大的浪费,文本文件的大小会因此大出二三倍,这是无法接受的。

它们造成的结果是:

1)出现了 Unicode 的多种存储方式,也就是说有许多种不同的二进制格式,可以用来表示 Unicode。

2)Unicode 在很长一段时间内无法推广,直到互联网的出现。

UTF-8

互联网的普及,强烈要求出现一种统一的编码方式。UTF-8 就是在互联网上使用最广的一种 Unicode 的实现方式。其他实现方式还包括 UTF-16(字符用两个字节或四个字节表示)和 UTF-32(字符用四个字节表示),不过在互联网上基本不用。

这里的关系是,UTF-8 是 Unicode 的实现方式之一。

UTF-8 最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。

5.节点流,处理流

节点流:直接从数据源或目的地读写数据

处理流:不直接连接到数据源或目的地,而是“连接”在已存 在的流(节点流或处理流)之上,通过对数据的处理为程序提 供更为强大的读写功能。

常用流

InputStream/Reader:向外边读数据

OutpusStream/Writer:向外边写数据

节点流(文件流)

import java.io.*;

public class Main {

    public static void main(String args[]) throws IOException
{
/**
* 读取文件
* 1.建立一个流对象,将已存在的一个文件加载进流。
*  FileReader fr = new FileReader(new File(“Test.txt”));
* 2.创建一个临时存放数据的数组。
*  char[] ch = new char[1024];
* 3.调用流对象的读取方法将流中的数据读入到数组中。
*  fr.read(ch);
* 4. 关闭资源。
*  fr.close();
*/ FileReader fr = null; fr = new FileReader(new File("c:\\file.txt"));
char[] buf = new char[1024];
int len;
while ((len = fr.read(buf)) != -1)
{
System.out.print(new String(buf, 0, len));
}
fr.close(); /**
* 写入文件
* 1.创建流对象,建立数据存放文件
*  FileWriter fw = new FileWriter(new File(“Test.txt”));
* 2.调用流对象的写入方法,将数据写入流
*  fw.write(“atguigu-songhongkang”);
* 3.关闭流资源,并将流中的数据清空到文件中。
*  fw.close();
*/ FileWriter fw = new FileWriter(new File("d:\\filewriter.txt"));
fw.write("9999999999999"); fw.close(); /**
* 在写入一个文件时,如果使用构造器FileOutputStream(file),则目录下有同名文
* 件将被覆盖。
*  如果使用构造器FileOutputStream(file,true),则目录下的同名文件不会被覆盖,
* 在文件内容末尾追加内容。
*/ }
}

缓冲流(一种处理流)

为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类 时,会创建一个内部缓冲区数组,缺省使用8192个字节(8Kb)的缓冲区。

缓冲流要“套接”在相应的节点流之上,根据数据操作单位可以把缓冲流分为:

BufferedInputStream BufferedOutputStream

BufferedReader BufferedWriter

只要关闭最外层流即可,关闭最外层流也 会相应关闭内层节点流。

flush()方法的使用:手动将buffer中内容写入文件。

import java.io.*;

public class Main {

    public static void main(String args[]) throws IOException
{ BufferedReader br = new BufferedReader(new FileReader("d:\\br.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("d:\\bw.txt")); String str;
while ((str = br.readLine()) != null) { // 一次读取字符文本文件的一行字符
System.out.println(str);
bw.write(str); // 一次写入一行字符串
bw.newLine(); // 写入行分隔符
}
bw.flush(); // 刷新缓冲区 br.close();
bw.close();
}
}

转换流

转换流提供了在字节流和字符流之间的转换

Java API提供了两个转换流:

InputStreamReader:将InputStream转换为Reader

OutputStreamWriter:将Writer转换为OutputStream

  • 字节流中的数据都是字符时,转成字符流操作更高效。
  • 很多时候我们使用转换流来处理文件乱码问题。实现编码和 解码的功能。
import java.io.*;

public class Main {

    public static void main(String args[]) throws IOException
{
/**
* 将old.txt中的文件读出写入到new.txt里
*/ FileInputStream fis = new FileInputStream("d:\\old.txt");
FileOutputStream fos = new FileOutputStream("d:\\new.txt"); InputStreamReader isr = new InputStreamReader(fis, "GBK");
OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK"); BufferedReader br = new BufferedReader(isr);
BufferedWriter bw = new BufferedWriter(osw); String str = null;
while ((str = br.readLine()) != null) {
bw.write(str);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
}
}


参考资料:

字符编码笔记:ASCII,Unicode 和 UTF-8https://link.zhihu.com/?target=http%3A//www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html

数据读写API——IO流的更多相关文章

  1. Java API —— IO流(数据操作流 & 内存操作流 & 打印流 & 标准输入输出流 & 随机访问流 & 合并流 & 序列化流 & Properties & NIO)

    1.操作基本数据类型的流     1) 操作基本数据类型 · DataInputStream:数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型.应用程序可以使用数据输出 ...

  2. Java API —— IO流( FileInputStream & FileOutputStream & BufferedInputStream & BufferedOutputStream )

    1.IO流概述 · IO流用来处理设备之间的数据传输        · 上传文件和下载文件        · Java对数据的操作是通过流的方式 · Java用于操作流的对象都在IO包中   2.IO ...

  3. 【Android】数据存储-java IO流文件存储

    1.数据持久化:将在内存中的瞬时数据保存在存储设备中.瞬时数据:设备关机数据丢失.持久化技术提供一种机制可以让数据在瞬时状态和持久状态之间转换. 2.Android中简单的三种存储方式:文件存储.Sh ...

  4. Java API —— IO流小结

    练习题: 1.复制文本文件 package cn.itcast_01; import java.io.BufferedReader; import java.io.BufferedWriter; im ...

  5. 四种读写方案IO流 (JAVA)

    File类用于访问文件或目录的属性 流:指一连串流动的字符,是以先进先出的方式发送信息的通道.程序和数据源之间是通过流联系起来的. 第一套:字节流读取写入方案 FileInputStream :字节流 ...

  6. java IO流体系--通识篇

    1.I/O流是什么 Java的I/O流是实现编程语言的输入/输出的基础能力,操作的对象有外部设备.存储设备.网络连接等等,是所有服务器端的编程语言都应该具备的基础能力. I = Input(输入),输 ...

  7. 分享知识-快乐自己:IO流基本操作

    点我参考常用API: IO图解: 相关理论: 流的概念和作用: 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将 ...

  8. java IO流详解

    流的概念和作用 学习Java IO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...

  9. IO流

    流的概念和作用 学习JavaIO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特 ...

随机推荐

  1. 个人永久性免费-Excel催化剂功能第49波-标准数据结构表转报表样式结果

    中国的企业信息化,已经过去了20年,企业里也产生了大量的数据,IT技术的信息化管理辅助企业经营管理也已经得到广泛地认同,现在就连一个小卖部都可以有收银系统这样的信息化管理介入.但同时也有一个很现实的问 ...

  2. 整合SSM框架必备基础—SpringMVC(下)

    在上一篇文章<整合SSM框架必备基础-SpringMVC(上)>中,胖达介绍了关于SpringMVC的诞生.优势以及执行流程等理论知识点,这篇文章打算在实操中加深一下对SpringMVC的 ...

  3. python课堂整理20----生产者消费者模型

    一.实现功能:店铺生产包子,消费者来吃 import time def producter(): ret = [] for i in range(10): time.sleep(0.1) ret.ap ...

  4. 【TensorFlow 1】操作变量

    打印 在tf中直接打印只是输出变量格式,如: #代码 data1 = tf.constant(2,dtype=tf.int32) #浮点数据 data2 = tf.Variable(10,name=' ...

  5. PageHelper分页实战(SSM整合)

    步骤一:引入SSM相关的jar包,包列表如下: 步骤二:创建或修改配置文件,配置文件清单如下: applicationContext.xml <?xml version="1.0&qu ...

  6. Metrics类型

    Metrics类型 在上一小节中我们带领读者了解了Prometheus的底层数据模型,在Prometheus的存储实现上所有的监控样本都是以time-series的形式保存在Prometheus内存的 ...

  7. windows server2008下搭建ftp服务

    在工作中不光使用linux系统下的ftp服务,也得使用windows下的,今天领导让我做一个,踩了很多坑,终于是做完了,重现下过程,我们就来一步一步搭建我们的windows下的ftp服务器: 1.环境 ...

  8. 关于报错:The Microsoft.ACE. Oledb.12.0 provider was not registered on the local computer

    错误描述:The Microsoft.ACE. Oledb.12.0 provider was not registered on the local computer 最近在Web项目中做一个自动生 ...

  9. python 简单的实现文件内容去重

    文件去重 这里主要用的是set()函数,特别地,set中的元素是无序的,并且重复元素在set中自动被过滤. 测试文本为 data.txt 具体代码如下: // 文件去重 #!/usr/bin/env ...

  10. JavaScript数据结构——集合的实现与应用

    与数学中的集合概念类似,集合由一组无序的元素组成,且集合中的每个元素都是唯一存在的.可以回顾一下中学数学中集合的概念,我们这里所要定义的集合也具有空集(即集合的内容为空).交集.并集.差集.子集的特性 ...