彻底学会IO流

概述:
  • IO流就是用来处理设备间数据传输问题的.常见的应用: 文件复制; 文件上传; 文件下载
  • IO的数据传输,可以看做是一种数据的流动,按照流动的方向,已内存为参照物,进行读写操作
  • IO可以保存到文件,其实就是内存在读取,内存在写入,而且不会消失,字节流可以操作任何类型的文件(音频、图文)都可以
IO流分类:

根据数据的流向分为:

  • 输入流(Input) :把数据从其他设备上读取到内存中的流。
  • 输出流(Output) :把数据从内存中写出到其他设备上的流。

根据数据的类型分为:

  • 字节流 :以字节为单位,读写数据的流。(通用的,可以操作任何类型的数据)
  • 字符流 :以字符为单位,读写数据的流。(方便用户操作文本的)

注意:

计算中所有的数据视频,音频,图片,文字…都是以字节的形式存储的

什么场景用什么流

用记事本打开看得懂的就可以用字符,看不懂的可以用字节(字节是万能流)

字节流:
  • InputStream:这个抽象类是表示字节输入流的所有类的超类
  • OutputStream:这个抽象类是表示字节输出流的所有类的超类
  • 子类名特点:子类名称都是以其父类名作为子类名的后缀

字节输出流:

FileOutputStream(String name):创建文件输出流以指定的名称写入文件

方法名说明
void write(int b)将指定的字节写入此文件输出流 一次写一个字节数据
void write(byte[] b)将数组中的数据写入流中 一次写一个字节数组数据
void write(byte[] b, int off, int len)将数组的一部分数据写入流中 int off: 从哪个索引开始 int len:写多少个
FileOutputStream​(File file, boolean append)当append设置为true时,不会删除之前的文件,追加写数据

代码演示:

public class Demo01 {public static void main(String[] args) throws IOException {// 创建字节输出流:文件不存在就创建,文件存在就清空原文件,// 第二个参数是续写开关,默认为false不续写,为true就续写,续写不会删除原来的文件内容FileOutputStream fos = new FileOutputStream("/Users/itzhuzhu/Desktop/Java/ideaTest/io/a.txt",true);// 一次写一个字节数组:写整数传到文件里的是码表对应值byte []  bytes = {97,98,99,100};fos.write(bytes);// 换行fos.write("\r\n".getBytes());// 从指定索引开始写数据(数据源,哪里开始,哪里结束)// getBytes(): 使用平台的默认字符集将字符串编码为 byte 序列,并将结果存储到一个新的 byte 数组中。fos.write(bytes,1,2);// 释放资源:告诉系统这个文件使用完毕fos.close();}
}

换行:

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

字节流写数据异常处理:
finallly:被finally控制的语句一定会执行,除非JVM退出

    public static void main(String[] args) {FileOutputStream fos = null;try {System.out.println(2 / 0); // 制造异常fos = new FileOutputStream("/Users/itzhuzhu/Desktop/Java/ideaTest/io/a.txt", true);} catch (FileNotFoundException e) {e.printStackTrace();}try {fos.write(99);} catch (IOException e) {e.printStackTrace();} // 为了避免空指针异常在这里要加判断,不为空才走finally {if (fos != null) {try {fos.close();} catch (IOException e) {e.printStackTrace();}}}}

字节输入流:

FileInputStream(String name):通过打开与实际文件的连接来创建一个FileInputStream,该文件由文件系统中的路径名name命名

方法名说明
public int read​()从输入流读取下一个字节数据, 返回读取到的字节
public int read(byte[] b)从输入流读取最多b.length个字节的数据
    public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("/Users/itzhuzhu/Desktop/Java/ideaTest/file/a.txt");int len;// 不是-1就可以一直读,是-1说明没了while ((len = fis.read()) != -1) {System.out.println((char) len);}fis.close();}

复制文件:

public class Demo03 {public static void main(String[] args) throws IOException {// 创建字节输入/输出流FileInputStream fis = new FileInputStream("/Users/itzhuzhu/Desktop/Java/ideaTest/io/a.txt");FileOutputStream fos = new FileOutputStream("/Users/itzhuzhu/Desktop/Java/ideaTest/io/a2.txt");// 数组可以装多个字节,一次读一个数组比一次读一个字节快byte[] bytes = new byte[1024];// 循环读取,len表示现在读了多少字节int len;while ((len = fis.read(bytes)) != -1) {fos.write(bytes, 0, len);}fis.close();fos.close();}
}

复制文件执行流程图
在这里插入图片描述

字节缓冲流:
  • 缓冲流只提供缓冲区,也就是数组,存在的使命就是提高效率,速度飞快。
  • 底层会创建一个默认8192的数组,主要是在硬盘和内存之间数据传递的次数,提高效率
  • 字节缓冲流要传入的参数是字节流,不能直接传入文件路径

在这里插入图片描述

构造方法:

方法名说明
BufferedOutputStream(OutputStream out)创建字节缓冲输出流对象
BufferedInputStream(InputStream in)创建字节缓冲输入流对象

缓冲流复制文件:
用一次一个数组,不要玩一个字节,哪个牛逼用哪个

    public static void main(String[] args) throws IOException {// 创建字节缓冲输入流、缓冲流会在底层创建一个8192字节数组BufferedInputStream bis = new BufferedInputStream(new FileInputStream("/Users/itzhuzhu/Desktop/Java/ideaTest/io/a.txt"));// 创建字节缓冲输出流BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("/Users/itzhuzhu/Desktop/Java/ideaTest/io/a2.txt"));byte[] bytes = new byte[1024];int len;while ((len = bis.read(bytes)) != -1) {bos.write(bytes, 0, len);}bis.close();bos.close();}
字符流:

有了万能的字节流为啥还出现了字符流?

  • 因为字节流读写中文可能会出现乱码,原因是因为编码表
  • 把字符存计算机要转二进制,叫编码
  • 把计算机中的二进制数据解析出来,叫解码
  • 编码和解码的方式必须一致,否则就会乱码

为什么字节流读中文乱码:

  • 字节流一次都一个字节,但是中文在GBK和UTF-8中都大于一个字节,也就是读不完一个完整的文字
编码表:
  • ASCll编码只有一些基础的文字,码表查看:http://ascii.911cha.com/
  • Unicode编码表是统一的万国码,容纳世界上所有的常见文字和符号,经UTF-8编码后一个中文占3个字节存储
  • GBK是中国推出的码表,每个国家都有自己的码表,但是比较乱,就定义了一个规范就是Unicode
  • UTF-8不是码表是一个格式
  • win系统默认使用GBK,一个字符占2个字节,idea默认用UTF-8,一个字符占3个字节

字符串中的编码解码:

方法名说明
byte[] getBytes()使用平台的默认字符集将该 String编码为一系列字节
byte[] getBytes(String charsetName)使用指定的字符集将该 String编码为一系列字节
String(byte[] bytes)使用平台的默认字符集解码指定的字节数组来创建字符串
String(byte[] bytes, String charsetName)通过指定的字符集解码指定的字节数组来创建字符串
public class Demo01 {public static void main(String[] args) throws UnsupportedEncodingException {//定义一个字符串String s = "放眼整个中国,谁特么有我帅";// 编码byte[] bys = s.getBytes("GBK");byte[] bys2 = s.getBytes("UTF-8");System.out.println(Arrays.toString(bys));System.out.println(Arrays.toString(bys2));// 解码byte [] byte1   = {-73, -59, -47, -37, -43, -5, -72, -10, -42, -48, -71, -6, -93, -84, -53, -83, -52, -40, -61, -76, -45, -48, -50, -46, -53, -89};byte [] byte2   = {-26, -108, -66, -25, -100, -68, -26, -107, -76, -28, -72, -86, -28, -72, -83, -27, -101, -67, -17, -68, -116, -24, -80, -127, -25, -119, -71, -28, -71, -120, -26, -100, -119, -26, -120, -111, -27, -72, -123};System.out.println(new String(byte1, "GBK"));System.out.println(new String(byte2, "UTF-8"));}
}
字符流读中文过程:
  • 不管在哪个码表中,中文的第一个字节一定是负数。
  • 用字符读的时候,当看到是负数就会看看是什么格式,UTF8就直接读三个,GBK就读2个
  • 字符流=字节流+编码表
字节流字符流怎么选:

要拷贝就用字节流&字节缓冲流
把文本数据读到内存用字符输入,内存写到文件用字符输出

字符流写数据:

构造方法

方法名说明
FileWriter(File file)根据给定的 File 对象构造一个 FileWriter 对象
FileWriter(File file, boolean append)根据给定的 File 对象构造一个 FileWriter 对象
FileWriter(String fileName)根据给定的文件名构造一个 FileWriter 对象
FileWriter(String fileName, boolean append)根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象

成员方法:

方法名说明
void write(int c)写一个字符
void write(char[] cbuf)写入一个字符数组
void write(char[] cbuf, int off, int len)写入字符数组的一部分
void write(String str)写一个字符串
void write(String str, int off, int len)写一个字符串的一部分
    public static void main(String[] args) throws IOException {FileWriter fw = new FileWriter("/Users/itzhuzhu/Desktop/Java/ideaTest/io/a.txt");// void write(int c)	写一个字符fw.write(99);// void write(char[] cbuf)	写入一个字符数组// 写的是int整数打印出来就是对应的ASCll码表,String类型就是原样输出char[] chars = {97, 98, 99, 100};fw.write(chars);// void write(char[] cbuf, int off, int len)	写入字符数组的一部分fw.write(chars, 0, chars.length);// void write(String str)	写一个字符串String s = "彭于晏都不着急结婚我急个锤子";fw.write(s);// void write(String str, int off, int len)	写一个字符串的一部分fw.write(s, 0, 2);fw.close();}
刷新和关闭的方法:
方法名说明
flush()刷新流,之后还可以继续写数据
close()关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据
public class Demo03 {public static void main(String[] args) throws IOException {FileWriter fw = new FileWriter("/Users/itzhuzhu/Desktop/Java/ideaTest/io/a.txt");fw.write("活到老,学到老");fw.flush();fw.write("走我了吗flush");fw.close();// fw.write("走我了吗close");  当场异常}
}
字符流读取:

构造方法

方法名说明
FileReader(File file)在给定从中读取数据的 File 的情况下创建一个新 FileReader
FileReader(String fileName)在给定从中读取数据的文件名的情况下创建一个新 FileReader

成员方法

方法名说明
int read()一次读一个字符数据
int read(char[] cbuf)一次读一个字符数组数据
    public static void main(String[] args) throws IOException {FileReader fr = new FileReader("/Users/itzhuzhu/Desktop/Java/ideaTest/io/a.txt");// int read():一次读一个字符数据int ch;while ((ch = fr.read()) != -1) {System.out.print((char) ch);}//int read(char[] cbuf):一次读一个字符数组数据int len;// 字符流不能用byte,打印也和字节流有点差别char[] chars = new char[1024];while ((len = fr.read(chars)) != -1) {System.out.println(new String(chars, 0, len));}fr.close();}
字符缓冲流:

构造方法

方法名说明
BufferedWriter(Writer out)创建字符缓冲输出流对象,可以指定缓冲区大小,或者可以接受默认大小
BufferedReader(Reader in)创建字符缓冲输入流对象,可以指定缓冲区大小,或者可以接受默认大小

字符缓冲流特有功能:

方法名说明
void newLine()写一行行分隔符,行分隔符字符串由系统属性定义
String readLine()读一行文字。 结果包含行的内容的字符串,不包括任何行终止字符如果流的结尾已经到达,则为null
public class Demo07 {public static void main(String[] args) throws IOException, IOException {BufferedWriter bw = new BufferedWriter(new FileWriter("/Users/itzhuzhu/Desktop/Java/ideaTest/io/a.txt"));bw.write("活到老");bw.newLine();bw.write("学到老");BufferedReader br = new BufferedReader(new FileReader("/Users/itzhuzhu/Desktop/Java/ideaTest/io/a.txt"));//一次读取一个字符数据/**int ch;while ((ch=br.read())!=-1) {System.out.print((char)ch);}*///一次读取一个字符数组数据char[] chs = new char[1024];int len;while ((len = br.read(chs)) != -1) {System.out.print(new String(chs, 0, len));}String s;// 一次读一行,返回的null不是-1,所以这里的判断条件为nullwhile ((s = br.readLine()) != null) {System.out.println(s);}br.close();}
}

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

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

相关文章

一些芯片资料

74hc14d u10 u11 u12 六反相触发器 74HC244 三态八缓冲器 u15 u13 uln2003afwg u16 74HC07 u17 L298N 步进电机驱动芯片 MOS管认知 转载于:https://www.cnblogs.com/legion/p/6908434.html

DP Intro - Tree DP Examples

因为上次比赛sb地把一道树形dp当费用流做了,受了点刺激,用一天时间稍微搞一下树形DP,今后再好好搞一下) 基于背包原理的树形DP poj 1947 Rebuilding Roads 题意:给你一棵树,让你求最少剪掉多少条边可以剪出一棵点数为m…

转换流/序列化/反序列化

转换流: 使用转换流可以在一定程度上避免乱码,还可以指定输入输出所使用的字符集 InputStreamReader:是从字节流到字符流的桥梁,父类是Reader OutputStreamWriter:是从字符流到字节流的桥梁,父类是Writer 转…

python+unittest框架整理(一点点学习前辈们的封装思路,一点点成长。。。)

预期框架整理目标: 1.单个用例维护在单个.py文件中可单个执行,也可批量生成组件批量执行 2.对定位参数,定位方法,业务功能脚本,用例脚本,用例批量执行脚本,常用常量进行分层独立,各自…

vs远程编译linux程序,使用Visual Studio 2015远程调试Linux程序

##安装 Visual Studio 2015安装时注意将跨平台移动开发->Visual C移动开发->Viaual C Android 开发的选项勾上##安装PUTTYVisual Studio依赖putty中的plink来连接Linux机器并发送命令##使用首先在Visual Studio中新建一个空项目这里是列表文本接下来将代码导入到这个空项…

都在说反射,反射到底是什么

概念: 什么是反射? 利用反射可以无视修饰符获取类里面所有的属性和方法对于任何对象,都能够调用它的方法和属性,这种动态获取信息以及动态调用对象方法的功能称为Java的反射 反射的应用场景? 常见的有: idea的智能提示、框架等…

LaunchScreen原理

会自动加载LaunchScreen是因为在Target当中,指定了Launch Screen file 它的底层实现其实把LaunchScreen上的东西,生成了一张图片,然后把这张图片设为程序的启动图片.可以进入沙盒当中查看,查看方法,找到应用程序根目录.获取方法: NSLog("%",NSHomeDirectory());打印出…

Mac - 苹果电脑mac系统释放硬盘空间方法汇总

硬盘空间是大家最头痛的一个问题,大家在硬盘空间变小的时候怎么腾空间的呢?下面为大家分享7个mac系统释放空间的高级方法,大家赶紧来收了! mac系统释放硬盘空间方法: 方法一:删除Emacs——可以节省出60MB的…

XML语言

XML: XML是可扩展的标记语言 标记语言: 通过标签来描述数据的一门语言(标签有时我们也将其称之为元素) 可扩展:标签的名字是可以自定义的,XML文件是由很多标签组成的,而标签名是可以自定义的 xml学习网站https://www.w3school.com.cn/x.asp 作用&#xf…

xml中的Document和Attribute

1.Document 导入dom4j的步骤 去官网下载 zip 包。http://www.dom4j.org/ 在项目中创建一个文件夹:lib将dom4j-2.1.1.jar文件复制到 lib 文件夹在jar文件上点右键,选择 Add as Library -> 点击OK在类中导包使用 得到Document对象 步骤:…

XPath表达式

什么是XPath XPath:路径表达式 作用:在DOM解析XML时,通过XPath表达让解析更加简单 XPath表达式分类 绝对路径相对路径全文搜索属性查找 什么是Node对象 DOM树中的每个节点就是Node dom4j中与XPath相关的方法 注:使用XPat…

最详细MySQL的安装与介绍Windows

数据库的安装: 打开下载的mysql安装⽂件双击解压缩,运⾏“mysql-5.5.40-win32.msi”。 选择安装类型,有“Typical(默认)”、“Complete(完全)”、“Custom(⽤户⾃定义)”…

读懂基础机器学习算法

本篇内容主要是面向机器学习初学者,介绍常见的机器学习算法,当然,欢迎同行交流。 哲学要回答的基本问题是从哪里来、我是谁、到哪里去,寻找答案的过程或许可以借鉴机器学习的套路:组织数据->挖掘知识->预测未来。…

在c语言中有函数leapyear定义如下,职业教育概论——职业教育的发展历史超星尔雅答案题库...

职业职业展历有时候,文学造诣高的中国诗歌翻译者在用词华丽方面超过莎士比亚。有int型变量x,教育教育i,j,k,则表达式x(i5,j6,k7)的值为( )从数据表student中查询张姓的所有学生,概论正确的SQL语句是( )史超世界上第一个…

tomcat安装启动配置

服务器: 服务器的概念非常的广泛,它可以指代一台特殊的计算机(相比普通计算机运行更快、负载更高、价格更贵),也可以指代用于部署网站的应用。我们这里说的服务器,其实是web服务器,或者应用服务…

JS在页面限制checkbox最大复选数

应该是挺简单的代码, 记录一下分享. 首先最直接的想法就是使用循环, 用局部变量记录已选的checkbox, 达到最大值就将余下的checkbox都禁止选择, 例如以下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ""> <html xmlns"…

c语言 二维数组 文库,c语言二维数组练习题

c语言二维数组练习题 (3页)本资源提供全文预览&#xff0c;点击全文预览即可全文预览,如果喜欢文档就下载吧&#xff0c;查找使用更方便哦&#xff01;19.90 积分完成下列程序代码完成下列程序代码1、 将二维数组(5 行 5 列)的右上半部分置零。 即&#xff1a;1234510000678910…

android陀螺仪轨迹,陀螺仪轨迹法长距离管道测量精度实测分析

陀螺仪轨迹法长距离管道测量精度实测分析陀螺仪轨迹法用于非开挖管道的精准坐标与位置测量已被电力与燃气等行业逐步了解与接受&#xff0c;近两年不断被引入到城市地下管线探测及电力与燃气管道验收标准中。由于管道埋于地下往往不能眼见为实&#xff0c;作为一种新的测量方式…

Spring IOC详解与配置

Spring&#xff1a; 框架&#xff1a; 具有一定功能的半成品软件&#xff0c;基于框架会节省开发成本 框架作用&#xff1a; 提高开发效率、复用性、编写规范、节约维护成本、解耦底层实现原理 Spring&#xff1a; Spring是分层的JavaSE/EE应用full-stack轻量级开源框架Sprin…

android8.0的蓝牙版本,android o 新特性详解 安卓8.0蓝牙音频增强以及更加可爱的表情包...

android 8.0什么时候推出&#xff1f;有哪些新特色&#xff1f;很多安卓用户非常想知道答案吧&#xff01;不用着急&#xff0c;下面是大麦子小编整理出来的安卓8.0新特性详解&#xff0c;希望可以帮到大家。有媒体近日曝光了有关谷歌Pixel XL 2手机会首发Android 8.0系统。现在…