博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IO【字节流、高效流】
阅读量:4880 次
发布时间:2019-06-11

本文共 7359 字,大约阅读时间需要 24 分钟。

微信公众号:

第11天 IO流
今日内容介绍
    字节流
    缓冲流
今日学习目标
    能够使用字节输出流写出数据到文件
    能够使用字节输入流读取数据到程序
    能够理解读取数据read(byte[])方法的原理
    能够使用字节流完成文件的复制
    能够使用字节缓冲流读取数据到程序
    能够使用字节缓冲流写出数据到文件
    能够完成单级文件夹复制
第1章    IO
1.1    IO概述
回想之前写过的程序,数据都是在内存中,一旦程序运行结束,这些数据都没有了,等下次再想使用这些数据,可是已经没有了。那怎么办呢?能不能把运算完的数据都保存下来,下次程序启动的时候,再把这些数据读出来继续使用呢?其实要把数据持久化存储,就需要把内存中的数据存储到内存以外的其他持久化设备(硬盘、光盘、U盘等 ROM)上。
当需要把内存中的数据存储到持久化设备上这个动作称为输出(写)Output操作。
当把持久设备上的数据读取到内存中的这个动作称为输入(读)Input操作。
因此我们把这种输入和输出动作称为IO操作。

1.2    IO流流向分类
按照流向分:输入流与输出流,每个IO流对象均要绑定一个IO资源
分类关系如下:
字节输入流 InputStream 抽象类
FileInputStream 操作文件的字节输入流
字节输出流 OutputStream 抽象类
FileOutputStream 操作文件的字节输出流
按照传输方式:分为字节流和字符流
   字符流  按照字符的方式读写
   字节流  按照字节的方式读写

1.3    一切均为字节

在数据传输过程中,一切数据(文本、图像、声音等)最终存储的均为一个个字节,即二进制数字。所以数据传输过程中使用二进制数据可以完成任意数据的传递。
为什么打开一个文本文件 我们看到的不是0101001这些数据?
我们向一个文件中存储一定的数据(一些数字),如果使用文本方式打开,则会以文本的方式解释数据。如果以视频的方式打开,则会以视频的方式解释数据。音频、可行执行文件等亦是如此。所以,在文件传输过程中,我们要时刻明确,传输的始终为二进制数据。

第2章    字节流

既然一切数据都是字节,那么字节流如何操作呢,那么接下来我们进行字节流的学习.
2.1    字节输出流OutputStream
OutputStream此抽象类,是表示输出字节流的所有类的超类。操作的数据都是字节,定义了输出字节流的基本共性功能方法。
输出流中定义都是写write方法,如下图:

2.1.1    FileOutputStream类
OutputStream有很多子类,其中子类FileOutputStream可用来写入数据到文件。
FileOutputStream类,即文件输出流,是用于将数据写入 File的输出流。

    构造方法

2.1.2    FileOutputStream类写入数据到文件中(三个方法)

    将数据写到文件中,
    步骤
    1.创建输出流对象
    2.调用输出流对象的写数据方法
    3.释放资源
    代码演示:

public class FileOutputStreamDemo {
    public static void main(String[] args) throws IOException { //需求:将数据写入到文件中。 //创建存储数据的文件。 File file = new File("c:\\file.txt"); //创建一个用于操作文件的字节输出流对象。一创建就必须明确数据存储目的地。 //输出流目的是文件,会自动创建。如果文件存在,则覆盖。 FileOutputStream fos = new FileOutputStream(file); //调用父类中的write方法。 byte[] data = "abcde".getBytes(); fos.write(data); //关闭流资源。 fos.close(); } }

2.1.3    给文件中续写和换行

我们直接new FileOutputStream(file)这样创建对象,写入数据,会覆盖原有的文件,那么我们想在原有的文件中续写内容怎么办呢?
继续查阅FileOutputStream的API。发现在FileOutputStream的构造函数中,可以接受一个boolean类型的值,如果值true,就会在文件末位继续添加。
    构造方法

    给文件中续写数据和换行,代码演示:

public class FileOutputStreamDemo2 {
    public static void main(String[] args) throws Exception { File file = new File("c:\\file.txt"); FileOutputStream fos = new FileOutputStream(file, true); String str = "\r\n"+"itcast"; fos.write(str.getBytes()); fos.close(); } }

2.2    字节输入流InputStream

通过前面的学习,我们可以把内存中的数据写出到文件中,那如何想把内存中的数据读到内存中,我们通过InputStream可以实现。InputStream此抽象类,是表示字节输入流的所有类的超类。,定义了字节输入流的基本共性功能方法。

    int read():读取一个字节并返回,没有字节返回-1.
    int read(byte[]): 读取一定量的字节数,并存储到字节数组中,返回读取到的字节数。
2.2.1    FileInputStream类
InputStream有很多子类,其中子类FileInputStream可用来读取文件内容。
FileInputStream 从文件系统中的某个文件中获得输入字节。
    构造方法
2.2.2    FileInputStream类读取数据read方法(只读纯英文,有空介绍一下读中文问题)
在读取文件中的数据时,调用read方法,实现从文件中读取数据
    从文件中读取数据,代码演示:

public class FileInputStreamDemo {
    public static void main(String[] args) throws IOException { File file = new File("c:\\file.txt"); //创建一个字节输入流对象,必须明确数据源,其实就是创建字节读取流和数据源相关联。 FileInputStream fis = new FileInputStream(file); //读取数据。使用 read();一次读一个字节。 int ch = 0; while((ch=fis.read())!=-1){ System.out.println("ch="+(char)ch); } // 关闭资源。 fis.close(); } }

2.2.3    读取数据read(byte[])方法

在读取文件中的数据时,调用read方法,每次只能读取一个,太麻烦了,于是我们可以定义数组作为临时的存储容器,这时可以调用重载的read方法,一次可以读取多个字符。

public class FileInputStreamDemo2 {
    public static void main(String[] args) throws IOException { /* * 演示第二个读取方法, read(byte[]); */ File file = new File("c:\\file.txt"); // 创建一个字节输入流对象,必须明确数据源,其实就是创建字节读取流和数据源相关联。 FileInputStream fis = new FileInputStream(file); //创建一个字节数组。 byte[] buf = new byte[1024];//长度可以定义成1024的整数倍。 int len = 0; while((len=fis.read(buf))!=-1){ System.out.println(new String(buf,0,len)); } fis.close(); } }

2.3    字节流练习

既然会了文件的读和写操作了,那么我们就要在这个基础上进行更为复杂的操作。使用读写操作完成文件的复制。
2.3.1    复制文件
原理;读取一个已有的数据,并将这些读到的数据写入到另一个文件中。

public class CopyFileTest {
    public static void main(String[] args) throws IOException { //1,明确源和目的。 File srcFile = new File("c:\\YesDir\test.JPG"); File destFile = new File("copyTest.JPG"); //2,明确字节流 输入流和源相关联,输出流和目的关联。 FileInputStream fis = new FileInputStream(srcFile); FileOutputStream fos = new FileOutputStream(destFile); //3, 使用输入流的读取方法读取字节,并将字节写入到目的中。 int ch = 0; while((ch=fis.read())!=-1){ fos.write(ch); } //4,关闭资源。 fos.close(); fis.close(); } }

上述代码输入流和输出流之间是通过ch这个变量进行数据交换的。

上述复制文件有个问题,每次都从源文件读取一个,然后在写到指定文件,接着再读取一个字符,然后再写一个,一直这样下去。效率极低。
2.3.2    临时数组方式复制文件
上述代码复制文件效率太低了,并且频繁的从文件读数据,和写数据,能不能一次多把文件中多个数据都读进内容中,然后在一次写出去,这样的速度一定会比前面代码速度快。

public class CopyFileByBufferTest {
    public static void main(String[] args) throws IOException { File srcFile = new File("c:\\YesDir\test.JPG"); File destFile = new File("copyTest.JPG"); // 明确字节流 输入流和源相关联,输出流和目的关联。 FileInputStream fis = new FileInputStream(srcFile); FileOutputStream fos = new FileOutputStream(destFile); //定义一个缓冲区。 byte[] buf = new byte[1024]; int len = 0; while ((len = fis.read(buf)) != -1) { fos.write(buf, 0, len);// 将数组中的指定长度的数据写入到输出流中。 } // 关闭资源。 fos.close(); fis.close(); } }

第3章    缓冲流

在我们学习字节流与字符流的时候,大家都进行过读取文件中数据的操作,读取数据量大的文件时,读取的速度会很慢,很影响我们程序的效率,那么,我想提高速度,怎么办?
Java中提高了一套缓冲流,它的存在,可提高IO流的读写速度
缓冲流,根据流的分类分类字节缓冲流与字符缓冲流。
在基础班我们已经学习过字符缓冲流了,那么今天学习一下字节缓冲流。
3.1    字节缓冲流
字节缓冲流根据流的方向,共有2个
    写入数据到流中,字节缓冲输出流 BufferedOutputStream
    读取流中的数据,字节缓冲输入流 BufferedInputStream

它们的内部都包含了一个缓冲区,通过缓冲区读写,就可以提高了IO流的读写速度

3.1.1    字节缓冲输出流BufferedOutputStream
通过字节缓冲流,进行文件的读写操作 写数据到文件的操作  
    构造方法
public BufferedOutputStream(OutputStream out)创建一个新的缓冲输出流,以将数据写入指定的底层输出流。

public class BufferedOutputStreamDemo01 {
    public static void main(String[] args) throws IOException { //写数据到文件的方法 write(); } /* * 写数据到文件的方法 * 1,创建流 * 2,写数据 * 3,关闭流 */ private static void write() throws IOException { //创建基本的字节输出流 FileOutputStream fileOut = new FileOutputStream("abc.txt"); //使用高效的流,把基本的流进行封装,实现速度的提升 BufferedOutputStream out = new BufferedOutputStream(fileOut); //2,写数据 out.write("hello".getBytes()); //3,关闭流 out.close(); } }

3.1.2    字节缓冲输入流 BufferedInputStream

刚刚我们学习了输出流实现了向文件中写数据的操作,那么,现在我们完成读取文件中数据的操作
    构造方法
public BufferedInputStream(InputStream in)

    /*      * 从文件中读取数据      * 1,创建缓冲流对象      * 2,读数据,打印      * 3,关闭      */     private static void read() throws IOException { //1,创建缓冲流对象 FileInputStream fileIn = new FileInputStream("abc.txt"); //把基本的流包装成高效的流 BufferedInputStream in = new BufferedInputStream(fileIn); //2,读数据 int ch = -1; while ( (ch = in.read()) != -1 ) { //打印 System.out.print((char)ch); } //3,关闭 in.close(); }

3.1.3    复制单级文件夹

/*   * 数据源:e:\\demo  * 目的地:e:\\test  *   * 分析:  *         A:封装目录  *         B:获取该目录下的所有文本的File数组  *         C:遍历该File数组,得到每一个File对象  *         D:把该File进行复制  */ public class CopyFolderDemo { public static void main(String[] args) throws IOException { // 封装目录 File srcFolder = new File("e:\\demo"); // 封装目的地 File destFolder = new File("e:\\test"); // 如果目的地文件夹不存在,就创建 if (!destFolder.exists()) { destFolder.mkdir(); } // 获取该目录下的所有文本的File数组 File[] fileArray = srcFolder.listFiles(); // 遍历该File数组,得到每一个File对象 for (File file : fileArray) { // System.out.println(file); // 数据源:e:\\demo\\e.mp3 // 目的地:e:\\test\\e.mp3 String name = file.getName(); // e.mp3 File newFile = new File(destFolder, name); // e:\\test\\e.mp3 copyFile(file, newFile); } } private static void copyFile(File file, File newFile) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream( file)); BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(newFile)); byte[] bys = new byte[1024]; int len = 0; while ((len = bis.read(bys)) != -1) { bos.write(bys, 0, len); } bos.close(); bis.close(); } }

欢迎关注菜鸟永恒,每天进步一小点。

转载于:https://www.cnblogs.com/starsyh/p/10264527.html

你可能感兴趣的文章
硬盘相关知识
查看>>
[LeetCode] Largest Rectangle in Histogram
查看>>
2345网址导航源码 v3.3
查看>>
JS重要知识点
查看>>
java解析数据
查看>>
改变 C/C++ 控制台程序的输出颜色和样式
查看>>
ADO constants include file for VBScript
查看>>
ExtJs4.2 RadioGroup CheckboxGroup
查看>>
InnoDB Undo Log
查看>>
在Application中集成Microsoft Translator服务之使用http获取服务
查看>>
flask页面中Head标签内容为空问题
查看>>
Centos7 Putty SSH密钥登录
查看>>
HDU 6330--Visual Cube(构造,计算)
查看>>
小说Symbian的签名
查看>>
Objective-C中ORM的运用:实体对象和字典的相互自动转换
查看>>
高级java面试宝典
查看>>
声明,本博客文章均为转载,只为学习,不为其他用途。感谢技术大牛的技术分享,让我少走弯路。...
查看>>
centos7.1下 Docker环境搭建
查看>>
c# 导出Excel
查看>>
Status: Checked in and viewable by authorized users 出现在sharepoint 2013 home 页面
查看>>