JAVAEE细细看 进阶 11 - IO、 字节流

1 篇文章 0 订阅
1 篇文章 0 订阅

IO、 字节流

一. IO流概述

a. IO: 输入和输出
b. 流: 是一种抽象概念,是对数据传输的总称
c. IO流就是用来处理设备间数据传输的,常见应用,文件复制,上传,下载

二. IO流概述和分类

按数据的流向,
输出流:写数据
输入流:读数据
按类型分,
字节流:打开读不懂的,就是字节流,不清楚该用什么的,也用字节流
字符流:打开读的懂的,就是字符流

三. 抽象类 InputStream、OutputStream

字节流写数据

FileOutputStream fi = new FileOutputStream("myByteStream/fileI.txt");
/*
做了3件事
a. 调用系统功能创建了文件
b. 创建了字节流对象
c. 让字节输出流对象指向创建好的文件
 */
fi.write(99);

/*
a. 关闭此文件输出流
b. 释放与此有关联的任何系统资料
 */
fi.close();

写数据的3种方式
-write(int b) 一次写一个字节数据
-write(byte[] b) 一次写一个字节数组数据
-write(byte[] b, int off, int len) 字节数组从off开始,len长度的一段写入

 FileOutputStream fo = new FileOutputStream("myByteStream/fo.txt");
        fo.write(97);
        fo.write(97);
        byte[] bt = {10, 20 ,89, 96, 96, 96, 96, 95, 93, 93, 93};
//        fo.write(bt);
        fo.write(bt, 2,5);
        fo.close();

1:字节流写数据如何实现换行呢?
window: \r\n
linux: \n
mac: \r

2:字节流写数据如何实现追加写入呢?
public FileOutputStream(String name, boolean append)
throws FileNotFoundException

/** 实现换行 */
//创建字节输出流对象
FileOutputStream fos = new FileOutputStream("myByteStream/fos.txt");

//写数据
for (int i = 0; i < 10; i++) {
    fos.write("hello".getBytes());
    fos.write("\r\n".getBytes());
}

//释放资源
fos.close();

/** 实现追加写入 */
FileOutputStream fo = new FileOutputStream("myByteStream/fos.txt",true);

//写数据
for (int i = 0; i < 10; i++) {
    fo.write("world".getBytes());
    fo.write("\r\n".getBytes());
}

//释放资源
fo.close();
四. 字节流写数据加异常处理

-因为try catch的时候,如果出现异常,会执行不到close,资源还在被暂用着,这时需要用到finally
finally:在处理异常时执行清除操作,比如IO流中释放资源;它一定会执行,除非JVM退出;
完整的,就长这个挫样子

FileOutputStream fos = null;
try {
     fos = new FileOutputStream("myByteStream\\fos.txt");
    fos.write("hello".getBytes());
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (fos != null){
        try {
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
五. 字节流读数据

read() 一次读一个字节数据,返回值是-1,则表示已经读取完毕

// 创建
FileInputStream fis = new FileInputStream("myByteStrean/fos.txt");

// 读
int bt;
while ((bt = fis.read()) != -1) {
    System.out.println((char)bt);
}

// 关闭
fis.close();

案例:
读 1.txt内的内容,复制到2.txt中

// 字节流 - 读
FileInputStream fis = new FileInputStream("myByteStream/fos.txt");

// 字节流 - 写
FileOutputStream fos = new FileOutputStream("myByteStream/foo.txt",true);

// 读、写
int bt;
while ((bt = fis.read()) != -1) {
    fos.write(bt);
}

// 关闭
fis.close();
fos.close();

一次读取一个 “字节数组”的数据

FileInputStream fis = new FileInputStream("myByteStream/fos.txt");

//存储器
byte[] by = new byte[1024]; // 一次读取1024的倍数

int len;
while ((len = fis.read(by)) != -1) {
    System.out.print(new String(by));
}

fis.close();

案例:使用字节流复制图片,到目的地文件夹

// 字节流 - 读
FileInputStream fis = new FileInputStream("/Users/thor/desktop/1.png");
// 字节流 - 写
FileOutputStream fos = new FileOutputStream("/Users/thor/desktop/copyPng/2.png");

// 读、写
byte[] by = new byte[1024]; // 1024的存储器
int len;
while ((len = fis.read(by)) != -1) {
    fos.write(by,0, len);
/*
 这里要用 0 和len, 因为数组是重复使用,例子:第一次循环by被填满了,第二次填数据是可能只替换了前800个数据,
 … by[788] = a, by[799] = b; 后面的224个数据还是上一个循环的数据,并没有被替换掉,数据就错误了;
*/
}

// 关闭
fis.close();
fos.close();

六. 字节缓冲流:
BufferOutputStream   
BufferedInputStream

构造方法:
字节缓冲输出流:BufferedOutputStream​(OutputStream out)
字节缓冲输入流:BufferedInputStream​(InputStream in)

// 读数据
// 方式 一
FileInputStream fos1 = new FileInputStream("myByteStream/foo.txt");
BufferedInputStream bfi1 = new BufferedInputStream(fos1);

// 方式二
BufferedInputStream bfi = new BufferedInputStream(new FileInputStream("myByteStream/foo.txt"));
/* 字节输出流在创建文件的时候,会把原文件覆盖掉,如果不想覆盖,就要append true */
BufferedOutputStream bfo = new BufferedOutputStream(new FileOutputStream("myByteStream/fos.txt",true));

// 读写方式一 ,一次读一个字节
int by;
while ((by = bfi.read()) != -1) {
    bfo.write(by);
}

// 读写方式二,一次读多个字节
byte[] byt = new byte[1024];
int len;
while ((len = bfi.read(byt)) != -1) {
    bfo.write(byt,0,len);   //
}

// 关闭
bfi.close();
bfo.close();

七. 案例

四种方式实现复制视频,并记录每种方式复制视频的时间
1:基本字节流一次读写一个字节
2:基本字节流一次读写一个字节数组
3:字节缓冲流一次读写一个字节
4:字节缓冲流一次读写一个字节数组

 //记录开始时间
 long startTime = System.currentTimeMillis();

 // 复制视频
 // 1:基本字节流一次读写一个字节
 FileInputStream fi = new FileInputStream("/Users/home/desktop/1.avi");
 FileOutputStream fo = new FileOutputStream(“/home/thor/desktop/avi/2.avi");

 /*// 一次读一个字节  共耗时:97650毫秒
 int by;
 while ((by = fi.read()) != -1) {
     fo.write(by);
 }*/

/* // 一次读多个字节   共耗时:264毫秒
 byte[] by = new byte[1024];
 int len;
 while ((len = fi.read(by)) != -1){
     fo.write(by,0,len);
     *//*
     这里要用 0 和len, 因为数组是重复使用,例子:第一次循环by被填满了,第二次填数据是可能只替换了前800个数据,
        … by[788] = a, by[799] = b; 后面的224个数据还是上一个循环的数据,并没有被替换掉,数据就错误了;
      *//*
 }*/

// 3:字节缓冲流
 BufferedInputStream bfi = new BufferedInputStream(fi);
 BufferedOutputStream bfo = new BufferedOutputStream(fo);

/* //  一次读写一个字节  共耗时:936毫秒
 int len;
 while ((len = bfi.read()) != -1){
     bfo.write(len);
 }*/

// 一次读写一个字节数组  66毫秒
 byte[] by = new byte[1024];
 int len;
 while ((len = bfi.read(by)) != -1) {
     bfo.write(by, 0, len);
 }

 // 关闭
 fi.close();
 fo.close();


 //记录结束时间
 long endTime = System.currentTimeMillis();
 System.out.println("共耗时:" + (endTime - startTime) + "毫秒");

八. 总结在这里插入图片描述
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值