一、字节流的概念
JDK 中提供了两个抽象类InputStream ,OutputStream, 它们是字节流的顶级父类,
在IO操作结束后,应该调用close()方法关闭流,从而释放当前IO流所占的系统资源
InputStream ,OutputStream的体系结构??? 图
二、字节流读写文件
针对文件的读写,JDK专门提供了两个类,分别是FileInputStream 和 FileOutputStream
1、从文件中读取字节
package cn.itcast.chapter07.example01;
import java.io.*;
/**
* 字节流对文件数据的读取
*/
public class Example01 {
public static void main(String[] args) throws Exception {
// 创建一个文件字节输入流
FileInputStream in = new FileInputStream("test.txt");
int b = 0; // 定义一个int类型的变量b,记住每次读取的一个字节
while (true) {
b = in.read(); // 变量b记住读取的一个字节
if (b == -1) { // 如果读取的字节为-1,跳出while循环
break;
}
System.out.println(b); // 否则将b写出
}
in.close(); //一定要关闭!
}
}
注:实际运行中报错,找不到指定的文件
2、把字节写入文件
(1)覆盖式写入
//字符串 转为 字符数组
byte[] b = str.getBytes();
package cn.itcast.chapter07.example02;
import java.io.*;
/**
* 使用FileOutputStream将数据写入文件
*/
public class Example02 {
public static void main(String[] args) throws Exception {
// 创建一个文件字节输出流
FileOutputStream out = new FileOutputStream("D:\\11111111FILES\\工作了\\学习资料\\JAVA\\Java基础案例教程\\源代码\\教材源码\\example.txt");
String str = "传智播客";
byte[] b = str.getBytes();
for (int i = 0; i < b.length; i++) {
out.write(b[i]);
}
out.close();
}
}
(2)追加式写入
package cn.itcast.cn.itcast.example03;
import java.io.FileOutputStream;
import java.io.OutputStream;
/**
* @author wangyue
* @version 1.0
* @date 2019/7/1 9:03
* @describe:
*/
public class Example03 {
public static void main(String[] args) {
OutputStream out = new FileOutputStream("D:\\11111111FILES\\工作了\\学习资料\\JAVA\\Java基础案例教程\\源代码\\教材源码\\example.txt", true);
String string = " huanyinni";
byte[] bytes = string.getBytes();
for (int i = 0; i < bytes.length; i++) {
out.write(bytes[i]);
}
out.close();
}
}
或者
public class Example03 {
public static void main(String[] args) throws Exception {
try {
OutputStream out = new FileOutputStream("D:\\11111111FILES\\工作了\\学习资料\\JAVA\\Java基础案例教程\\源代码\\教材源码\\example.txt", true);
String string = " huanyinni";
byte[] bytes = string.getBytes();
for (int i = 0; i < bytes.length; i++) {
out.write(bytes[i]);
}
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 由于IO流进行数据读写操作时会出现异常,使用了throws关键字将异常抛出,然而一旦遇到异常,IO流的close()方法将无法得到执行,占用的系统资源将得不到释放,因此,为了保证IO流的close()方法必须执行,通常将关闭流的操作写在finally代码块中,
finally {
try {
if ( in != null )
in.close();
} catch ( Exception e ) {
e.printStackTrace ();
}
try {
if (out !=null)
out.close();
} catch ( Exception e ) {
e.printStackTrace();
}
}
package cn.itcast.cn.itcast.example03;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* @author wangyue
* @version 1.0
* @date 2019/7/1 9:03
* @describe:
*/
public class Example03 {
public static void main(String[] args) {
OutputStream out = null;
try {
out = new FileOutputStream("D:\\11111111FILES\\工作了\\学习资料\\JAVA\\Java基础案例教程\\源代码\\教材源码\\example.txt", true);
String string = " huanyinni";
byte[] bytes = string.getBytes();
for (int i = 0; i < bytes.length; i++) {
out.write(bytes[i]);
}
} catch (Exception e) {
e.printStackTrace();
} finally { //不进入try的部分
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
三、文件的拷贝
package cn.itcast.chapter07.example04;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
/**
* 文件的拷贝
*/
public class Example04 {
public static void main(String[] args) throws Exception {
//1、创建一个字节输入流,用于读取当前目录下source文件夹中的mp3文件
InputStream in = new FileInputStream("D:\\11111111FILES\\工作了\\学习资料\\JAVA\\Java基础案例教程\\源代码\\教材源码\\第7章 IO\\chapter07\\source\\五环之歌.mp3");
//2、创建一个文件字节输出流,用于将读取的数据写入target目录下的文件中
OutputStream out = new FileOutputStream("D:\\11111111FILES\\工作了\\学习资料\\JAVA\\Java基础案例教程\\源代码\\教材源码\\第7章 IO\\chapter07\\target\\五环之歌.mp3");
int len; // 定义一个int类型的变量len,记住每次读取的一个字节
long begintime = System.currentTimeMillis(); // 获取拷贝文件前的系统时间
//3、读取文件
while ((len = in.read()) != -1) { // 读取一个字节并判断是否读到文件末尾
out.write(len); // 将读到的字节写入文件
}
long endtime = System.currentTimeMillis(); // 获取文件拷贝结束时的系统时间
System.out.println("拷贝文件所消耗的时间是:" + (endtime - begintime) + "毫秒");
//4、释放资源
in.close();
out.close();
}
}
输出
拷贝文件所消耗的时间是:14566毫秒
四、字节流的缓冲区
当通过流的方式拷贝文件时,为了提高效率也可以定义一个字节数组作为缓冲区,在拷贝文件时,可以一次性读取多个字节的数据,并保存在字节数组中,然后将字节数组中的数据一次性写入文件
package cn.itcast.chapter07.example05;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
/**
* 文件的拷贝(使用缓冲区拷贝文件)
*/
public class Example05 {
public static void main(String[] args) throws Exception {
//1、创建一个字节输入流,用于读取当前目录下source文件夹中的mp3文件
InputStream in = new FileInputStream("D:\\11111111FILES\\工作了\\学习资料\\JAVA\\Java基础案例教程\\源代码\\教材源码\\第7章 IO\\chapter07\\source\\五环之歌.mp3");
//2、创建一个文件字节输出流,用于将读取的数据写入当前目录的target文件中
OutputStream out = new FileOutputStream("D:\\11111111FILES\\工作了\\学习资料\\JAVA\\Java基础案例教程\\源代码\\教材源码\\第7章 IO\\chapter07\\target\\五环之歌.mp3");
//3、以下是用缓冲区读写文件
byte[] buff = new byte[1024]; // 定义一个字节数组,作为缓冲区
// 定义一个int类型的变量len记住读取读入缓冲区的字节数
int len;
long begintime = System.currentTimeMillis();
while ((len = in.read(buff)) != -1) { // 判断是否读到文件末尾 len=读进换取区的字节数量
out.write(buff, 0, len); // 从第一个字节开始,向文件写入len个字节
}
long endtime = System.currentTimeMillis();
System.out.println("拷贝文件所消耗的时间是:" + (endtime - begintime) + "毫秒");
//4、释放资源
in.close();
out.close();
}
}
输出
拷贝文件所消耗的时间是:30毫秒
五、字节缓冲流
在IO包中提供两个带缓冲的字节流,分别是BufferedInputStream和BufferedOutputStream,他们的构造方法中分别接受InputStream和OutputStream类型的参数作为对象,在读写数据时提供缓冲功能,
package cn.itcast.chapter07.example06;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
* BufferedInputStream和BufferedOutputStream 这两个流的用法
*/
public class Example06 {
public static void main(String[] args) throws Exception {
// 创建一个带缓冲区的输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\11111111FILES\\工作了\\学习资料\\JAVA\\Java基础案例教程\\源代码\\教材源码\\第7章 IO\\chapter07\\src.txt"));
// 创建一个带缓冲区的输出流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\11111111FILES\\工作了\\学习资料\\JAVA\\Java基础案例教程\\源代码\\教材源码\\第7章 IO\\chapter07\\des.txt"));
int len;
while ((len = bis.read()) != -1) {
bos.write(len);
}
bis.close();
bos.close();
}
}