IO流:
包括字节流和字符流。

在这里解释一下我对于流的理解,其实流就相当于一个用来运输字节或者字符的管道,一开始会把所有的数据存放到流中,然后我们再从流中取出数据(进行读取或者写出操作),每读或者写一次就会从管道中把读或者写的数据取出来,管道中就没有了你刚才读到或者写出的数据了。比如:
FileInputStream fis = new FileInputStream(String filename);
就会把文件名为filename的文件内容全部存放到管道中去,然后我们进行fis.read(),就会从管道中读取出内容,读到的内容就会从管道中消失。

字节流:

(1)InputStream:抽象了应用程序读取数据的方式
OutputStream : 抽象了应用程序写出数据的方式
(2)输入流的基本方法:
InputStream in = new InputStream();
int b = in.read();
读取一个字节无符号填充到int的最后8位,返回的是读到的字节(转换成int类型的值的)内容,当读到-1时,标识读取到最后结束了。
in.read(byte[] buf):读取的数据填充到字节数组buf中,返回的是读到的字节的个数。
in.read(byte[] buf,int start ,int size):读取数据到字节数组buf,并且是从buf的start位置开始,最多存放size长度的数据,返回的是读到的字节的个数。
(3)输出流的基本方法:
OutputStream out = new OutputStream();
out.write(int b):写出一个字节到流,写的是int的最后的8位
out.write(byte[] buf):将buf字节数组都写入到流
out.write(byte[] buf,int start,int size):字节数组buf从start位置开始写size长度的字节到流

下面介绍字节流基本的读取方法的使用(注意:FileInputStream继承了InputStream)

package com.test.FileInputStream;import java.io.FileInputStream;
import java.io.IOException;public class FileInputStreamTest {public static void main(String[] args) {try {System.out.println("方式一:字节数组的长度足够存储读取的内容");ReadFile1("C:\\Users\\Administrator\\Desktop\\javaIO\\读取的测试文件.txt");System.out.println();System.out.println("方式二:字节数组的长度不足以存储读取的内容");ReadFile2("C:\\Users\\Administrator\\Desktop\\javaIO\\读取的测试文件.txt");} catch (IOException e) {e.printStackTrace();}}/*** 当字节数组的大小足够存储读取的内容的时候* 只读取一次,然后打印出来就可以了*/public static void ReadFile1(String filename) throws IOException{FileInputStream fis = new FileInputStream(filename);byte[] buf = new byte[1024];//从fis中批量读取字节,放入到buf这个字节数组中, //从第0个位置开始放,最多放buf.length个 //返回的是读到的字节的个数int bytes = fis.read(buf, 0, buf.length);int j = 1;for(int i=0;i<bytes;i++){//byte类型8位,int类型32位,为了避免数据转换错误,通过&0xff将高24位清零System.out.print(Integer.toHexString(buf[i]&0xff)+" ");if(j++%10==0){//每读取10个字节就换行System.out.println();}}fis.close();}/*** 当数组的大小没法存储读取的全部的字节的时候,* 就要对该字节数组进行重复利用,* 每读取字节数组的长度的内容的时候就打印出来,* 然后再次读取该字节数组长度的内容,* 直到把所有的内容读取出来*/public static void ReadFile2(String filename) throws IOException{FileInputStream fis = new FileInputStream(filename);byte[] buf = new byte[1024];int bytes = 0;int j = 1;while((bytes = fis.read(buf, 0, buf.length))!=-1){//如果数组不是足够大,要进行多次的读取操作for(int i = 0;i<bytes;i++){System.out.print(Integer.toHexString(buf[i]&0xff)+" ");if(j++%10==0){System.out.println();}}}fis.close();}
}

读取的文件内容:

读取结果截图:

下面对比下单字节读取与批量读取文件的效率:

package com.test.FileInputStream;import java.io.FileInputStream;
import java.io.IOException;
/*** 对比单字节读取与批量读取同样的文件的所用的时间* 2015年8月8日 下午9:24:31**/
public class FileInputStreamTest1 {public static void main(String[] args) {try {ReadFile1("C:\\Users\\Administrator\\Desktop\\javaIO\\问尘 - 洛天依.mp3");ReadFile2("C:\\Users\\Administrator\\Desktop\\javaIO\\问尘 - 洛天依.mp3");} catch (IOException e) {e.printStackTrace();}}/*** 单字节读取文件的方式* @param filename* @throws IOException*/public static void ReadFile1(String filename) throws IOException{FileInputStream fis = new FileInputStream(filename);int b;int i = 1;long start = System.currentTimeMillis();while((b = fis.read())!=-1){
//          System.out.print(Integer.toHexString(b&0xff)+" ");if(i++%10==0){
//              System.out.println();}}long end = System.currentTimeMillis();System.out.println("单字节读取所用的时间:"+(end-start));fis.close();}/*** 批量字节读取的方式* @param filename* @throws IOException*/public static void ReadFile2(String filename) throws IOException{FileInputStream fis = new FileInputStream(filename);byte[] buf = new byte[1024];int b;int j = 1;long start = System.currentTimeMillis();while((b = fis.read(buf, 0, buf.length))!=-1){for(int i = 0;i<b;i++){
//              System.out.print(Integer.toHexString(buf[i]&0xff)+" ");if(j++%10==0){
//                  System.out.println();}}}long end = System.currentTimeMillis();System.out.println("批量读取所用的时间:"+(end-start));fis.close();}
}


所以,批量读取,对于大文件而言效率高,也是我们最常见的读文件的方式。单字节读取不适合大文件,大文件读取的效率很低。

下面介绍字节流基本的写出方法的使用(注意:FileOutputStream继承了OutputStream,实现了向文件中写出byte数据的方法)

package com.test.FileOutputStream;import java.io.FileOutputStream;
import java.io.IOException;public class FileOutputStreamTest {public static void main(String[] args) {try {WriteFile("C:\\Users\\Administrator\\Desktop\\javaIO\\写入测试文件.txt");} catch (IOException e) {e.printStackTrace();}}public static void WriteFile(String filename) throws IOException{//如果该文件不存在,则直接创建,如果存在,删除后创建FileOutputStream fos = new FileOutputStream(filename);
//      //如果该文件不存在,则直接创建,如果存在,直接在文件中追加内容
//      FileOutputStream fos = new FileOutputStream(filename,true);/** 写一个字符的方法(可以写一个字符)*/fos.write('A');//写出了‘A’的字节所占位的最后八位fos.write('B');/** 写一个整数的方法*/int i = 10;//write()方法只能写八位,那么写一个int需要写4次,每次8位fos.write(i>>>24);fos.write(i>>>16);fos.write(i>>>8);fos.write(i);/**写一个字节数组的方法 (可以直接写一个字节数组)*/byte[] gbk = "小灰灰".getBytes("gbk");fos.write(gbk);fos.close();}}

基本的字节输入流和字节输出流的整合运用:(以Copy文件为例)

package com.test.FileOutputStream;import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class CopyFile {public static void main(String[] args) {File srcFile = new File("C:\\Users\\Administrator\\Desktop\\javaIO\\被copy的文件.txt");File destFile = new File("C:\\Users\\Administrator\\Desktop\\javaIO\\copy的文件.txt");try {copyFile(srcFile, destFile);} catch (IOException e) {e.printStackTrace();}}public static void copyFile(File srcFile,File destFile) throws IOException{if(!srcFile.exists()){throw new IllegalArgumentException("文件:"+srcFile+"不存在");}if(!srcFile.isFile()){throw new IllegalArgumentException(srcFile+"不是文件");}FileInputStream fis = new FileInputStream(srcFile);FileOutputStream fos = new FileOutputStream(destFile);byte[] buf = new byte[3*1024];int i;while((i = fis.read(buf,0,buf.length))!=-1){fos.write(buf, 0, i);fos.flush();}fis.close();fos.close();}}

DataOutputStream/DataInputStream的使用:
作用:
对“流”功能的扩展,可以更加方便的读取int,long,字符等基本类型的数据。

构造方法:
DataOutputStream dos = new DataOutputStream(OutputStream out);
DataInputStream dis = new DataInputStream(InputStream in);
从构造方法中可以看到这两种流就是对普通流进行了包装,方便读取基本类型的数据。

DataOutputStream多出来的写出的方法:
writeInt()
writeDouble()
writeLong()
writeChars()//采用UTF-16BE编码写出
writeUTF()//采用UTF-8编码写出
……

writeInt():
write()方法一次只可以写出最后的8位,但是int类型的数据是32位(4个字节),所以要write()四次才能写出一个int类型的数据。

int i = 10;//write()方法只能写八位,那么写一个int需要写4次,每次8位fos.write(i>>>24);fos.write(i>>>16);fos.write(i>>>8);fos.write(i);

这是我们写一个int类型数据的方法。
writeInt()方法可以只写一次就可以写出一个int类型的数据,其实查看源码可以知道其实也是write()了四次。
writeInt()方法的源码:

 public final void writeInt(int v) throws IOException {out.write((v >>> 24) & 0xFF);out.write((v >>> 16) & 0xFF);out.write((v >>>  8) & 0xFF);out.write((v >>>  0) & 0xFF);incCount(4);}

writeLong(),writeDouble()……也是这样的原理。
所以可以看出DataOutputStream就是对基本类型的数据的写出方法进行了包装,方便我们写出基本类型的数据。

BufferedInputStream/BufferedOutputStream的使用:
这两个流为IO提供了带缓冲区的操作,一般打开文件进行写入或者读取操作时,都会加上缓冲,这种流模式提高了IO的性能。
解释:
从应用程序中把数据放入文件,相当于将一缸水倒入另一个缸中。
FileOutputStream—–>write()方法相当于一滴水一滴水的把水转过去
DataOutputStream—>writeXxx()方法会方便一些,相当于一瓢一瓢的转移过去
BufferedOutputStream—>write()方法更方便,相当于一瓢一瓢先放入桶中,再从桶中倒入到另个缸中,性能提高了。
注意:当使用BufferedOutputStream的时候,当写完一次后要进行冲刷缓冲区(flush()),否则下次进行写入的时候就没法向缓冲区中存放了。
下面比较一下这些流读取和写入操作的效率:

package com.test.FileInputStream;import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
/*** 对比单字节读取与批量读取同样的文件的所用的时间* 2015年8月8日 下午9:24:31**/
public class FileInputStreamTest1 {public static void main(String[] args) {try {ReadFile1("C:\\Users\\Administrator\\Desktop\\javaIO\\问尘 - 洛天依.mp3");ReadFile2("C:\\Users\\Administrator\\Desktop\\javaIO\\问尘 - 洛天依.mp3");ReadFile3("C:\\Users\\Administrator\\Desktop\\javaIO\\问尘 - 洛天依.mp3");ReadFile4("C:\\Users\\Administrator\\Desktop\\javaIO\\问尘 - 洛天依.mp3");} catch (IOException e) {e.printStackTrace();}}/*** 单字节读取文件的方式* @param filename* @throws IOException*/public static void ReadFile1(String filename) throws IOException{FileInputStream fis = new FileInputStream(filename);int b;int i = 1;long start = System.currentTimeMillis();while((b = fis.read())!=-1){
//          System.out.print(Integer.toHexString(b&0xff)+" ");if(i++%10==0){
//              System.out.println();}}long end = System.currentTimeMillis();System.out.println("单字节读取所用的时间:"+(end-start));fis.close();}/*** 批量字节读取的方式* @param filename* @throws IOException*/public static void ReadFile2(String filename) throws IOException{FileInputStream fis = new FileInputStream(filename);byte[] buf = new byte[1024];int b;int j = 1;long start = System.currentTimeMillis();while((b = fis.read(buf, 0, buf.length))!=-1){for(int i = 0;i<b;i++){
//              System.out.print(Integer.toHexString(buf[i]&0xff)+" ");if(j++%10==0){
//                  System.out.println();}}}long end = System.currentTimeMillis();System.out.println("批量读取所用的时间:"+(end-start));fis.close();}/*** 字节缓冲流读取文件* @param filename* @throws IOException*/public static void ReadFile3(String filename) throws IOException{FileInputStream fis = new FileInputStream(filename);BufferedInputStream bis = new BufferedInputStream(fis);long start = System.currentTimeMillis();int b;int j = 1;while((b=bis.read())!=-1){for(int i=0;i<b;i++){
//              System.out.println(Integer.toHexString(b&0xff)+" ");if(j++%10==0){
//                  System.out.println();}}}long end = System.currentTimeMillis();System.out.println("字节缓冲流读取所用的时间:"+(end-start));bis.close();}/*** 字节缓冲流批量读取文件* @param filename* @throws IOException*/public static void ReadFile4(String filename) throws IOException{FileInputStream fis = new FileInputStream(filename);BufferedInputStream bis = new BufferedInputStream(fis);byte[] buf = new byte[1024*3];long start = System.currentTimeMillis();int b;int j = 1;while((b= bis.read(buf, 0, buf.length))!=-1){for(int i = 1;i<b;i++){
//              System.out.println(Integer.toHexString(buf[i]&0xff)+" ");if(j++%10==0){
//                  System.out.println();}}}long end = System.currentTimeMillis();System.out.println("字节缓冲流批量读取所用的时间"+(end-start));bis.close();}
}

所用时间结果截图:

由此可以看出:
批量读取文件的效率>字符缓冲流读取文件的效率>单字节读取文件的效率

字节流--IO学习笔记(二)相关推荐

  1. wxpython应用程序对象与顶级窗口_wxPython学习笔记(二)

    如何创建和使用一个应用程序对象? 任何wxPython应用程序都需要一个应用程序对象.这个应用程序对象必须是类wx.App或其定制的子类的一个实例.应用程序对象的主要目的是管理幕后的主事件循环. 父类 ...

  2. Java IO学习笔记总结

    Java IO学习笔记总结 前言 前面的八篇文章详细的讲述了Java IO的操作方法,文章列表如下 基本的文件操作 字符流和字节流的操作 InputStreamReader和OutputStreamW ...

  3. 二维码学习笔记(二) | 数据分析与数据编码

    唠唠闲话 二维码笔记系列(原文地址): 『二维码学习笔记(一) | 二维码概述』 『二维码学习笔记(二) | 数据分析与数据编码』 『二维码学习笔记(三) | 纠错编码』 『二维码学习笔记(四) | ...

  4. 学习笔记二.矩阵按键

    #学习笔记二:GPIO的探索与矩阵按键 ##1.在配置cubemx时,对gpio的配置有开漏输出和推挽输出两种方式, ###这里有一篇文章(别人的文章)讲的很详细link戳这里跳转 通俗来讲,推挽输出 ...

  5. Netty学习笔记二网络编程

    Netty学习笔记二 二. 网络编程 1. 阻塞模式 阻塞主要表现为: 连接时阻塞 读取数据时阻塞 缺点: 阻塞单线程在没有连接时会阻塞等待连接的到达,连接到了以后,要进行读取数据,如果没有数据,还要 ...

  6. Spring Boot 框架学习笔记(二)(配置文件与数据注入 yaml基本语法 JSR303数据验证 多环境切换 )

    Spring Boot 框架学习笔记(二) 六.appliaction.properties配置与数据注入 6.1 `@Value`注解 测试注入数据 读取输入流 6.2 读取配置文件数据注入 单文件 ...

  7. 码匠社区学习笔记(二)

    所需资料 教程视频地址 Bootstrap spring模板 elasticsearch中文社区(想模仿的效果) 码云aAuth 获取授权用户的资料 github第三方授权文档 码匠社区学习笔记(二) ...

  8. qml学习笔记(二):可视化元素基类Item详解(上半场anchors等等)

    原博主博客地址:http://blog.csdn.net/qq21497936 本文章博客地址:http://blog.csdn.net/qq21497936/article/details/7851 ...

  9. [转载]dorado学习笔记(二)

    原文地址:dorado学习笔记(二)作者:傻掛 ·isFirst, isLast在什么情况下使用?在遍历dataset的时候会用到 ·dorado执行的顺序,首先由jsp发送请求,调用相关的ViewM ...

最新文章

  1. Spring Boot使用@Async实现异步调用:自定义线程池
  2. 销售订单屏幕增强及功能增强
  3. Redhat 7 进入救援模式
  4. WPF 入门教程StackPanel介绍
  5. 360极速浏览器代理设置无效问题
  6. 电脑网线,电脑网线主要分类
  7. 怎么把做好的ps保存成图片_ps存成jpg格式的快捷键,ps如何另存为图片格式
  8. Windows下软件提示“没有注册类”问题解决
  9. Webbrowser指定IE内核版本(更改注册表)
  10. 官方纯净版windows10教育版安装密钥极其下载地址
  11. WIN8.1硬盘安装及skype打英国免费电话激活
  12. 算法设计与分析: 4-3 磁带最优存储问题
  13. eclipse导入外部项目,package报错,显示红叉叉
  14. uni-app 使用web的echarts画图表
  15. 【锐捷无线】AP模式切换
  16. 朔日计算机基础答案,大学计算机基础课程练习系统 使用标准手册.doc
  17. php for continue,PHP跳出循环之“continue”实例详解
  18. 安装firebug插件
  19. cocos creator 3D艺术字体
  20. 初级php工程师考试,Autodesk AutoCAD Civil 3D初级工程师

热门文章

  1. ES6 模块化操作
  2. Centos配置在线yum源
  3. EnforceLearning:迁移学习-监督训练与非监督训练
  4. 深度学习:网络的编程模式比较
  5. redis缓存实现原理php,分析redis原理及实现
  6. 强网杯Web部分review
  7. Vagrant+VirtualBox版本的坑
  8. Bash 中的 $0 在什么时候不是 argv[0]
  9. javascript 比量str今天的日期是,参数diff
  10. httping 2.2.1 发布,测试 HTTP 连接的工具