Java基础教程——字节流
IO流
水流 | 特点 |
---|---|
连续性 | 逝者如斯夫,不舍昼夜; |
方向性 | 一江春水向东流。水往低处流。百川东到海,何时复西归?少壮不努力,老大徒伤悲! |
源头尽头 | 唯有源头活水来;覆水难收 |
Java里的IO也有这样的特点。
IO:数据从硬盘流向内存(Input),或者从内存流向硬盘(Output)。
IO流分类:
按照流的流向来分:输入流、输出流。
|-输入流:读入内存。
|-输出流:写出到硬盘等设备。
按操作数据单元分:字节流、字符流
|-字节流:8位
|-字符流:16位
按流的角色分:节点流、处理流。
|-节点流:特定的IO设备(如硬盘),也叫低级流
|-处理流:经过封装的流,也叫高级流、包装流,可以消除不同节点流的差异(典型的装饰器模式)
Java的IO流有40多个类,高抽象层的基类有四个:
字节流 | 字符流 | |
---|---|---|
输入流 | InputStream | Reader |
输出流 | OutputStream | Writer |
字节流
字节流:100100011010100010
可以操作所有文件,包括文本文件、视频、音频、压缩文件等等都可以用字节流读写。
两个重要的抽象类:
(1)抽象类 java.io.OutputStream,是输出字节流的所有类的超类
|--API方法摘要:
|--|--void write(byte[] b) 将 b.length 个字节从指定的 byte 数组写入此输出流。
|--|--abstract void write(int b) 将指定的字节写入此输出流。
|--|--void close() 关闭此输出流并释放与此流有关的所有系统资源。
(2)抽象类 java.io.InputStream,是输入字节流的所有类的超类
|--API方法摘要:
|--|--abstract int read()从输入流中读取数据的下一个字节。
|--|--int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。
|--|--void close() 关闭此输入流并释放与该流关联的所有系统资源。
FileOutputStream写文件
// 文件输出流。完整地说,是文件字节输出流。
public class FileOutputStream extends OutputStream
步骤:
1.创建流对象
2.调用write方法,把数据写入文件
3.释放资源
import java.io.*;
public class 文件字节输出流 {public static void main(String[] args) {File file = new File("文件字节输出流.txt"); // 创建文件对象try {// (1)构造:通过文件对象创建文件输出流对象FileOutputStream fos = new FileOutputStream(file);// (2)写入文件// (2.1)write(int b) 将"单个字节"写入到文件中for (int i = 49; i < 97; i++) {fos.write(i);fos.write(' ');}// (2.2)write(byte[] b) 将"字节数组"中的数据全部写入文件byte[] buffer = "I Love Java,你呢?".getBytes();fos.write(buffer);// (3)关闭流fos.close();} catch (IOException e) {e.printStackTrace();}}
}
追加:
使用构造方法:FileOutputStream(File file, boolean append)
// 构造:通过文件对象创建文件输出流对象// 附加第二个参数true,指定进行文件追加,默认为不追加fos = new FileOutputStream(file, true);
回车换行:
CR(carriage return),回车,\r
LF(line feed),换行,\n
windows:\r\n
linux或unix:\n
mac:\r
FileInputStream读文件
public class FileInputStream extends InputStream
import java.io.*;
public class 文件字节输入流 {static final int C_CONDITION = 2;public static void main(String[] args) {try {File file = new File("testRead.dat"); // 创建文件对象// 【1】创建输入流对象,相当于打开文件FileInputStream fis = new FileInputStream(file);if (C_CONDITION == 1) {// 【2】.read():读取单个字节for (int i = 0; i < file.length(); i++) {// 循环读取"字节",转为字符输出,英文没问题int read = fis.read();char ch = (char) read;System.out.print(ch);}System.out.println();} else {// 【2】.read(byte[] b):读取文件中的数据到字节数组// 根据文件的字节长度创建字节数组long len = file.length();byte[] buf = new byte[(int) len];fis.read(buf);// 利用字节数组创建字符串String str = new String(buf);System.out.println(str);}// 【3】关闭流fis.close();} catch (FileNotFoundException fnfe) {System.out.println("文件打开失败。");} catch (IOException ioe) {ioe.printStackTrace();}}
}
复制文件
package ahjava.io;
import java.io.*;
public class 复制文件 {public static void main(String[] args) {字节流复制文件();}static void 字节流复制文件() {File srcFile = new File("testRead.dat"); // 源文件对象File destFile = new File("testCopy.java"); // 目标文件对象if (destFile.exists()) {// 判断目标文件是否存在,存在则删除destFile.delete();}// 目标文件不存在才复制try {destFile.createNewFile();// 创建文件输入/输出流对象FileInputStream fis = new FileInputStream(srcFile);FileOutputStream fos = new FileOutputStream(destFile);// 创建字节数组,作为临时缓冲byte[] buf = new byte[128];System.out.println("开始复制文件...");int len = -1;// 循环从文件输入流中读取数据while ((len = fis.read(buf)) != -1) {System.out.println(len);// 写入到文件输出流中fos.write(buf, 0, len);}System.out.println("文件复制成功!");fis.close(); // 关闭流fos.close();} catch (IOException e) {e.printStackTrace();}}
}
上面的代码有哪些风险?
改进版:
static void 字节流复制文件2() {// 1.close()提取到finally中// 2.提取FilexxxStream对象// 3.初始化(否则不准close)// 4.close()时加判空语句FileInputStream fis = null;FileOutputStream fos = null;File srcFile = new File("testRead.dat"); // 源文件对象File destFile = new File("testCopy.java"); // 目标文件对象if (destFile.exists()) {// 判断目标文件是否存在,存在则删除destFile.delete();}// 目标文件不存在才复制try {destFile.createNewFile();fis = new FileInputStream(srcFile);fos = new FileOutputStream(destFile);// 创建字节数组,作为临时缓冲byte[] buf = new byte[128];System.out.println("开始复制文件...");int len = -1;// 循环从文件输入流中读取数据while ((len = fis.read(buf)) != -1) {System.out.println(len);// 写入到文件输出流中fos.write(buf, 0, len);}System.out.println("文件复制成功!");// 关闭流} catch (IOException e) {e.printStackTrace();} finally {if (fis != null) {try {fis.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}fis = null;}if (fos != null) {try {fos.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}fos = null;}}}
又臭又长!
Java 7异常处理写法:
try后面增加括号,其中定义流对象,该流对象仅在try中有效,执行完毕自动释放,不需要写finally。
try(流对象){
} catch (IOException e) {
}
具体代码如下:
static void 字节流复制文件3() {File srcFile = new File("testRead.dat"); // 源文件对象File destFile = new File("testCopy.java"); // 目标文件对象if (destFile.exists()) {// 判断目标文件是否存在,存在则删除destFile.delete();}// try(流对象)try (FileInputStream fis = new FileInputStream(srcFile);FileOutputStream fos = new FileOutputStream(destFile)) {destFile.createNewFile();// 创建字节数组,作为临时缓冲byte[] buf = new byte[128];System.out.println("开始复制文件...");int len = -1;// 循环从文件输入流中读取数据while ((len = fis.read(buf)) != -1) {System.out.println(len);// 写入到文件输出流中fos.write(buf, 0, len);}System.out.println("文件复制成功!");// 关闭流} catch (IOException e) {e.printStackTrace();}}
*Java9异常处理写法
觉得try里的代码太繁琐,try()中可以引入外部的变量:
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
try (fis;fos){...}
// ↑ 理想状态,代码并不能这么写
然而,fis、fos本身需要抛异常,如果直接try...catch,这两个变量会变成另外的try中的局部变量;
如果把声明提取到try之外,try (fis;fos)又需要变量是final的
FileInputStream fis = null;FileOutputStream fos = null;try {fis = new FileInputStream(srcFile);fos = new FileOutputStream(destFile);} catch (FileNotFoundException e1) {e1.printStackTrace();}try (fis;fos) {
CopyFile.java:20: 错误: 用作 try-with-resources 资源的变量 fis 既不是最终变量, 也不是实际上的最终变量
try (fis;fos) {
^
CopyFile.java:20: 错误: 用作 try-with-resources 资源的变量 fos 既不是最终变量, 也不是实际上的最终变量
try (fis;fos) {
所以,fis和fos需要往外抛出异常,外部调用的地方又需要捕获异常。比不用此功能还要麻烦。可运行代码如下:
import java.io.*;
public class CopyFile{public static void main(String[] args) {try {copyJDK9();} catch (FileNotFoundException e) {e.printStackTrace();}}static void copyJDK9() throws FileNotFoundException {File srcFile = new File("testRead.dat");File destFile = new File("testCopy.java");if (destFile.exists()) {destFile.delete();}FileInputStream fis = new FileInputStream(srcFile);FileOutputStream fos = new FileOutputStream(destFile);try (fis;fos) {destFile.createNewFile();byte[] buf = new byte[128];System.out.println("start copy...");int len = -1;while ((len = fis.read(buf)) != -1) {System.out.println(len);fos.write(buf, 0, len);}System.out.println("success");} catch (IOException e) {e.printStackTrace();}}
}
转载于:https://www.cnblogs.com/tigerlion/p/11179223.html
Java基础教程——字节流相关推荐
- Java基础教程:反射基础
Java基础教程:反射基础 引入反射 反射是什么 能够动态分析类能力的程序称为反射. 反射是一种很强大且复杂的机制. Class类 在程序运行期间,Java运行时系统始终为所有对象维护一个被称为运行时 ...
- Java基础教程:多线程基础(3)——阻塞队列
Java基础教程:多线程基础(3)--阻塞队列 快速开始 引入问题 生产者消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一存储空间,生产者向空间里生产数据,而消费者取走数据. 模 ...
- Java基础教程:面向对象编程[2]
Java基础教程:面向对象编程[2] 内容大纲 访问修饰符 四种访问修饰符 Java中,可以使用访问控制符来保护对类.变量.方法和构造方法的访问.Java 支持 4 种不同的访问权限. default ...
- Java基础教程(12)--深入理解类
一.方法的返回值 当我们在程序中调用方法时,虚拟机将会跳转到对应的方法中去执行.当以下几种情况发生时,虚拟机将会回到调用方法的语句并继续向下执行: 执行完方法中所有的语句: 遇到return语句: ...
- Java基础教程:Lambda表达式
Java基础教程:Lambda表达式 引入Lambda Java 是一流的面向对象语言,除了部分简单数据类型,Java 中的一切都是对象,即使数组也是一种对象,每个类创建的实例也是对象.在 Java ...
- Java基础教程:注解
Java基础教程:注解 本篇文章参考的相关资料链接: 维基百科:https://zh.wikipedia.org/wiki/Java%E6%B3%A8%E8%A7%A3 注解基础与高级应用:http: ...
- Java基础教程-刘刚-专题视频课程
Java基础教程-2704人已学习 课程介绍 Java基础教程是一套入门Java开发语言的课程,它是由浅入深的介绍Java基础内容,包括Java介绍.基本类型及运算符.控制执行流程.字 ...
- java基础教程(一)
Java 开发环境配置 在进行Java开发之前,需要先安装Java开发工具包(JDK)和集成开发环境(IDE).以下是Java开发环境的配置和搭建步骤: 下载JDK:访问Oracle官方网站,选择适合 ...
- java基础教程之实现一键分享朋友圈
java最新技术,实现一键分享朋友圈,下面给大家演示一下 作为十余年java老司机,根据多年经验,自己录制的学习视频,我往对你们有所帮助, 有技术问题或者面试方面交流的可以加我微信renlliang ...
- Java基础教程-10-多线程
Java基础教程-10-多线程 1. 多线程 我们在之前,学习的程序在没有跳转语句的前提下,都是由上至下依次执行,那现在想要设计一个程序,边打游戏边听歌,怎么设计? 要解决上述问题,咱们得使用多进程或 ...
最新文章
- 程序员也需要工匠精神
- linux下递归修改目录/文件权限命令
- C++ Primer 5th笔记(chap 10)泛型算法 :特定容器算法list
- java面向对象编程知识点总结
- 检测到在集成的托管管道模式下不适用的 ASP.NET 设置。
- easyui带表单的弹窗效果制作
- 【最全解析】1050 螺旋矩阵 (25分)
- 前端学习(1066):ES6里面的三个注意点1
- mysql数据存储和函数_MySQL数据库——存储和函数
- 解决:Gitlab上出现“You won‘t be able to pull or push project code via SSH until you add an SSH key to you
- Symbol()类型的定义及特点
- windows系统 Git Server git服务器自己搭建 (基于 Gitblit or Gogs )
- Atitit 发帖机实现(2)---usrQBN2243 文本解析到对象协议规范
- 大白话解析模拟退火算法、遗传算法
- 华为电脑Linux进pe,华为笔记本(HuaWei)如何进入BIOS设置U盘启动?
- 巨量创意signature
- 斯坦福发布3D街景数据集:8个3D城市模型+2500万图像+1.18亿图像配对
- 漫画:用木兰从军说外观模式
- 客户端单周发版下的多分支自动化管理与实践
- hdf知道这些就够了
热门文章
- python如何筛选数据_python如何在列表、字典中筛选数据
- defunct 进程占用端口_纯干货:23个服务器常见问题处理方法!
- asp.net mvc mysql 开源项目_【开源项目SugarSite】ASP.NET MVC+ Layui+ SqlSugar+RestSharp项目讲解...
- cmake 交叉编译_如何使用CMake编译RTT微内核
- 【LeetCode】205 Isomorphic Strings (c++实现)
- 食品安全和大数据物联网有什么关系
- TensorFlow 变量共享: get_variable
- 比特币技术Base58
- BZOJ2769 : YY的快速排序
- 使用CHM文档 采集随笔(续)