IO流

Posted diamonddavid

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IO流相关的知识,希望对你有一定的参考价值。

1.关于IO:

  • 用于处理设备之间的数据传输,如读写文件,网络通讯等
  • Java中,对于数据的输入/输出操作以“流/stream”的方式进行
  • jav.io包下提供各类“流”类和接口,用于获取不同种类的数据,并通过标准方法输入或者输出数据

 

2.IO流的原理和分类:

  • 按照数据单位不同:字节流、字符流
  • 按照数据流的流向不同:输入流、输出流
  • 按照流的角色不同:节点流、处理流:
  • 节点流:直接作用于文件上的就是节点流,就是在两个设备之间传输的
  • 处理流:在节点流之上又包了一层,凡是在已有流上包的一层就是处理流,可以起到比如说:加快流的传输速度等作用

输入流 ->

数据 ===================> 程序

<- 输出流

 

3.IO流体系

(抽象基类)  字节流  字符流

输入流    InputStream     Reader

输出流    OutputStream   Writer

下面所有的分类都是以上派生的!

 

4.流的体系结构

抽象基类    节点流(或流文件)    缓冲流(处理流的一种)

InputStream     FileInputStream      BufferedInputStream

OutputStream       FileOutputStream         BufferedOutputStream

Reader       FileReader          BufferedReader

Writer         FileWriter             BufferedWriter

 

一:节点流:

关于字符流的:

package day11;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class FileReaderWriterTest {

    public static void main(String[] args) {
        File file = new File("hello.txt");
        System.out.println(file.getAbsoluteFile());
    }

    public void testFileReader() throws IOException {
        //1.实例化File类对象,指明要操作的文件
        File file = new File("hello.txt"); //相较于当前project下的
        //2.提供具体的流
        FileReader fr = new FileReader(file);
        //3.数据的读入
        //read():返回读入的一个字符。如果达到文件末尾,返回-1
        int data = fr.read();
        while (data != -1){
            System.out.print((char)data);
            data = fr.read();
        }
        //4.流的关闭
        //必须要手动关闭,因为对于java的回收机制中,对于其他物理连接,比如数据库连接、输入流输出流、Socket连接无能为力
        fr.close();
    }

    //不抛出异常该怎么写?
    public void testFileReader1(){
        FileReader fr = null;
        try {
            //1.实例化File类对象,指明要操作的文件
            File file = new File("hello.txt"); //相较于当前project下的
            //2.提供具体的流
            fr = new FileReader(file);
            //3.数据的读入
            //read():返回读入的一个字符。如果达到文件末尾,返回-1
            int data;
            while ((data = fr.read()) != -1){
                System.out.print((char)data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4.流的关闭
            //必须要手动关闭,因为对于java的回收机制中,对于其他物理连接,比如数据库连接、输入流输出流、Socket连接无能为力
            try {
                fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    //对read()操作升级:使用read的重载方法
    public void testFileReader2(){
        FileReader fr = null;
        try {
            //1.File类的实例化
            File file = new File("hello.txt");
            //2.FileReader流的实例化
            fr = new FileReader(file);
            //3.读入的操作具体的细节
            //read(char[] cbub):返回每次读入cbuf数组中的字符的个数
            //如果达到文件末尾,返回-1
            char[] cbuf = new char[5]; //先创建为5个一波
            int len;
            while ((len = fr.read(cbuf)) != -1){
                //方式一:
//                错误的写法:
//                for (int i = 0; i < cbuf.length; i++) {
//                    System.out.print(cbuf[i]);
//                }
                //正确的:
                for (int i = 0; i < len; i++) {
                    System.out.print(cbuf[i]);
                }
                //方式二:
                //错误的写法,对应于方式一的写法错误
//                String str = new String(cbuf);
//                System.out.println(str);
                //正确的写法:
                //对应于方式二的写法:
                String str = new String(cbuf,0,len);
                System.out.println(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fr != null) {
                //4.资源的关闭
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    //从内存中写出数据到硬盘的文件里
    public void testFileWriter(){
        FileWriter fw = null;
        try {
            //1.提供File类的对象,指明写出到的文件
            File file = new File("hello1.txt");
            //2.提供FileWriter的对象,用于数据的写出
            fw = new FileWriter(file,true);
            ////写出时如果没有创建文件,那么就会自动创建文件
            //如果已经创建了这个文件
            //当后面append写的是false时,就会使得原来文件被覆盖
            //当后面的append写的是true时,就是使得原来的文件的内容往后接上
            //如果后面append什么也不加:那么就是默认false,对原来的文件覆盖
            //3.写出的操作
            fw.write("shit
");
            fw.write("fuck!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4.流资源的关闭
            if (fw != null) {
                try {
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    //文件的复制
    public void testFileReaderFileWriter(){
        FileReader fr = null;
        FileWriter fw = null;
        try {
            //1.创建File类的对象——2个——读入和写出的文件
            File srcFile = new File("hello.txt");
            File destFile = new File("hello2.txt");
            //2.创建流的对象——输入流和输出流
            fr = new FileReader(srcFile);
            fw = new FileWriter(destFile);
            //3.数据的读入和写出操作
            char[] cbuf = new char[5];
            int len; //记录每次读入到cbuf数组中的字符的个数
            while ((len = fr.read(cbuf)) != -1){
                //每次写出len个字符
                fw.write(cbuf,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fw != null) {
                    //4.关闭流资源
                    fw.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            try {
                if (fr != null) {
                    //4.关闭流资源
                    fr.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            //万一第一个try中出现异常,那么第二个还是可以执行到
        }
    }
}

 

关于字节流的:

package day11;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 测试FileInputStream和FileOutputStream的使用
 */
public class FileInputOutputStreamTest {

    public void testFileInputStream() throws IOException {
        FileInputStream fis = null;
        try {
            //1.造文件
            File file = new File("hello.txt");
            //2.造流
            fis = new FileInputStream(file);
            //3.读数据
            byte[] buffer = new byte[5];
            int len;
            while ((len = fis.read(buffer)) != -1) {
                String str = new String(buffer,0,len);
                System.out.print(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null){
                //.关闭
                fis.close();
            }
        }
    }

    public void testFileInputOutputStream(){
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            File file = new File("原图.jpg");
            File destFile = new File("原图.jpg");
            fis = new FileInputStream(file);
            fos = new FileOutputStream(destFile);
            byte[] buffer = new byte[5];
            int len;
            while ((len = fis.read(buffer)) != -1){
                fos.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    //指定路径下文件的复制
    public void copyFile(String srcPath,String destPath){
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            File file = new File(srcPath);
            File destFile = new File(destPath);
            fis = new FileInputStream(file);
            fos = new FileOutputStream(destFile);
            byte[] buffer = new byte[5];
            int len;
            while ((len = fis.read(buffer)) != -1){
                fos.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

 

结论:

1.对于文本文件(.txt, .java, .c, .cpp),使用字符流处理

2.对于非文本文件(.jpg, .mp3, .mp4, .avi, .doc, .ppt...),使用字节流来处理

 

二.缓冲流

读写速度相比于上面的方法更加快

package day11;

import java.io.*;

//作用:提高流的读取、写入速度
public class BufferedTest {
    //实现非文本文件的复制
    public void BufferedStreamTest(){
        FileInputStream fis = null;
        FileOutputStream fos = null;
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            //1.造文件
            File srcFile = new File("原图.jpg");
            File destFile = new File("原图2.jpg");
            //2.造流
            //2.1.造节点流
            fis = new FileInputStream(srcFile);
            fos = new FileOutputStream(destFile);
            //2.2.造缓冲流
            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);
            //3.复制的细节:读取,写入
            byte[] buffer = new byte[10];
            int len;
            while ((len = bis.read(buffer)) != -1){
                bos.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4.资源关闭:
            //要求:
            //先关闭外层的流,再关闭内层的流
            //说明:关闭外层流的同时,内层流也会自动关闭,所以关闭内层流的动作可以忽略
            if (bis != null){
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bos != null){
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
//            if (fis != null){
//                fis.close();
//            }
//            if (fos != null){
//                fos.close();
//            }
        }
    }

}

 

以上是关于IO流的主要内容,如果未能解决你的问题,请参考以下文章

在 .net 中处理 pcm wav 流

此应用小部件片段中所有意图 (PendingIntents) 的逻辑流

JavaSE 一些技巧 04——IO流各种流常用代码整理

猜数小游戏升级版(IO流实现,对IO流进行加强理解运用)

利用IO(文件字符流)打印代码本身

JAVA IO流相关代码(Serializable接口,管道流PipedInputStream类,RandomAccessFile类相关代码)