Java-IO流(IO流原理和流的分类)

Java IO流原理

1)I/O是input/Output的缩写,I/O技术是非常实用的技术,用于处理数据传输。如读/写文件,网络通讯等;

2)Java程序中,对于数据的输入和输出操作以“流(stream)”的方式进行;

3)java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过方法输入或输出数据;

4)输入(input):读取外部数据(磁盘、光盘等存储设备的数据到程序(内存)中);

5)输出(output):将程序(内存)数据输出到磁盘、光盘等存储设备中。

流的分类

1)按照操作数据单位不同分为:字节流(8bit),字符流(按字符)(分别按照字符和字节进行读取,如果从操作单位方面看字符流操作效率较高,但是操作二进制文件时字节流不会出现错误,字节流操作文本文件比较好);

2)按数据流的流向不同分为:输入流和输出流;

3)按流的角色不同分为:节点流,处理流(包装流);

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

字节输入流的顶级父类

InputStream

字符输入流的顶级父类

Reader

输出流

字节输出流的顶级父类

OutputStream

字符输出流的顶级父类

Writer

★Java的IO流共涉及40多个类,都是从如上4个抽象基类派生的;

★由这四个基类派生出来的子类名称以其父类名作为子类名后缀;

InputStream抽象类实现了Closeable接口,Closeable接口上面还有一个AutoCloseable接口;OutputStream抽象类实现了Closeable接口和Flushable接口;Reader抽象类实现了Closeable接口和Readable接口;Writer抽象类实现了Appendable接口、Flushable接口和Closeable接口;在使用时,创建他们的实现子类。

IO流字节流InputStream
OutputStream
字符流Reader
Writer
InputStreamFileInputStream
PipedInputStream
ObjectInputStream
ByteArrayInputStream
SequenceInputStream
FilterInputStreamBufferedInputStream
DigestInputStream
DataInputStream
OutputStreamFileOutputStream
PipedOutputStream
ObjectOutputStream
ByteArrayOutputStream
FilterOutputStreamBufferedOutputStream
DigestOutputStream
DataOutputStream
PrintStream
ReaderInputStreamReaderFileReader
BufferedReader
CharArrayReader
FilterReader
PipedReader
StringReader
WriterOutputStreamWriterFileWriter
BufferedWriter
CharArrayWriter
FilterWriter
PipedWriter
PrintWriter
StringWriter

InputStream常用子类

1)FileInputStream:文件输入流;

2)BufferedInputStream:缓冲字节输入流;

3)ObjectInputStream:对象字节输入流;

package com.pero.inputStream;

import org.junit.jupiter.api.Test;

import java.io.FileInputStream;
import java.io.IOException;

/**
 * @author Pero
 * @version 1.0
 */
public class FileInputStream_ {
    public static void main(String[] args) {

    }

    @Test
    //读取文件
    public void test(){
        //定义文件路径
        String filePath = "d:\\demo\\test\\HelloWorld.txt";
        //定义文件输入流对象名称
        FileInputStream fileInputStream = null;
        //定义接收读取一字节数据
        int readData;
        try {
            //获取文件输入流对象,用于读取文件
            fileInputStream = new FileInputStream(filePath);
            while ((readData = fileInputStream.read()) != -1){  //如果返回-1表示已经读取到最后一位
                System.out.print((char)readData); //读取数据为int型,需要转成字符型char
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {  //必须关闭流,释放链接文件的流,否则造成资源浪费
            try {
                fileInputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    @Test
    public void test2(){
        String path = "d:\\demo\\test\\HelloWorld.txt";
        FileInputStream fileInputStream = null;
        byte[] bytes = new byte[8];
        int readLength = 0;

        try {
            fileInputStream = new FileInputStream(path);
            //如果读取正常返回读取的字节数
            while((readLength = fileInputStream.read(bytes)) != -1){
                //第一次读取时,bytes第一次接收八个字符hello,wo;
                // 此时fileInputStream.read(bytes)返回值为8,
                //while循环不退出,输出hello,wo后,再次进入循环
                // 第二次读取bytes第二次接收rld!
                // 此时fileInputStream.read(bytes)返回值为4,
                // (bytes中存储的为rld!o,wo,其中o,wo为上次读取的数据,bytes中没有将其覆盖)
                //但是new String(bytes, 0, readLength)输出bytes数组的0~3(0~readLength-1)位的字符
                //第三次读取,读取到数据的最后一位,此时fileInputStream.read(bytes)返回值为-1退出循环
                System.out.print(new String(bytes,0,readLength));
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            try {
                fileInputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

    }
}

 OutputStream常用子类

1)FileOutputStream:文件输出流。

package com.pero.outputStream_;

import org.junit.jupiter.api.Test;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * @author Pero
 * @version 1.0
 */
public class FileOutputStream_ {
    public static void main(String[] args) {

    }

    @Test
    public void writeFile(){
        String path = "d:\\demo\\test\\next.txt";
        FileOutputStream fileOutputStream = null;

        try {
            //fileOutputStream = new FileOutputStream(path);以此方式创建输出流
            //输出文件内容会覆盖原来的内容
            //fileOutputStream = new FileOutputStream(path,true);以此方式创建输出流
            //输出文件内容会添加到原来的内容之后
            fileOutputStream = new FileOutputStream(path,true);
            //写入一个字节
            //fileOutputStream.write('H');

            //写入字符串
            String str = "Hello,world!";
            //使用getBytes,将字符串转成字节(byte)数组
            fileOutputStream.write(str.getBytes());

            //写入字符串部分数据Hello(0~5-1)
            fileOutputStream.write(str.getBytes(),0,5);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

文件拷贝(图像) 

package com.pero.outputStream_;

import org.junit.jupiter.api.Test;

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

/**
 * @author Pero
 * @version 1.0
 */
public class FileCopy {
    public static void main(String[] args) {

    }

    @Test
    public void copy(){
        //大文件读取中,边读取数据边输出存放文件(流的形式)
        //将地址所在文件数据输入到程序
        //输入、输出路径
        String inputPath = "C:\\Users\\Pero\\Desktop\\4.jpeg";
        //将文件数据输出到指定地址存放
        String outputPath = "D:\\demo\\test\\4.jpeg";
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        byte[] bytes = new byte[1024];  //饱和读取数量
        int readLength = 0;

        try {
            fileInputStream = new FileInputStream(inputPath);
            fileOutputStream = new FileOutputStream(outputPath);

            //读取文件数据
            while ((readLength = fileInputStream.read(bytes)) != -1){
                //边读边写,一定要用write(bytes,0,readLength);
                //因为最后一次读写,不一定把bytes里的存储数据完全覆盖,
                //最后剩余的空间是倒数第二次传输的部分数据,会发生错误
                fileOutputStream.write(bytes,0,readLength);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        finally {
            try {
                if (fileInputStream != null){
                    fileInputStream.close();
                }
                if (fileOutputStream != null){
                    fileOutputStream.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

 FileReader类和FileWriter类(字符流,按照字符来操作IO)

FileReader相关方法

1)构造器:new FileReader(File/String)

2)read:每次读取单个字符,则返回该字符,如果到了文件末尾则返回-1;

3)read(char[]):批量读取多个字符到数组,返回读取到的字符数,如果到了文件末尾则返回-1;

相关API:

1)new String(char[] ):将char[]转换阿成String;

2)new String(char[] ,off ,len):将char[]的指定部分转换成String。

package com.pero.reader_;

import org.junit.jupiter.api.Test;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/**
 * @author Pero
 * @version 1.0
 */
public class FileReader_ {
    public static void main(String[] args) {

    }

    @Test
    public void reader(){
        //创建路径
        String path = "d:\\demo\\test\\Story.txt";
        FileReader fileReader = null;
        int data = 0;
        //char[] chars = new char[1024];
        try {
            fileReader = new FileReader(path);
            //循环读取
            while ((data = fileReader.read()) != -1){
                System.out.print((char)data);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            try {
                if (fileReader != null){
                    fileReader.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    @Test
    public void reader1(){
        String path = "d:\\demo\\test\\Story.txt";
        char[] chars = new char[1024];
        int length = 0;
        FileReader fileReader = null;

        try {
            fileReader = new FileReader(path);
            while ((length = fileReader.read(chars)) != -1){
                System.out.print(new String(chars,0,length));
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            try {
                if (fileReader != null){
                    fileReader.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

FileWriter相关方法

1)构造器:new FileWriter(File/String):覆盖模式,相当于流的指针在首端;

2)构造器:new FileWriter(File/String,true):追加模式,相当于流的指针在尾端;

3)write(int ):写入单个字符;

4)write(char[]):写入指定数组;

5)write(char[],off,len):写入指定数组的指定部分;

6)write(String):写入整个字符串;

7)write(String,off,len):写入字符串的指定部分。

相关API:String类中toCharArray:将String转换成char[]。

★注意:FileWriter使用后,必须要关闭(close)或刷新(flush),否则写入不到指定的文件。

package com.pero.writer_;

import org.junit.jupiter.api.Test;

import java.io.FileWriter;
import java.io.IOException;

/**
 * @author Pero
 * @version 1.0
 */
public class FileWriter_ {
    public static void main(String[] args) {

    }

    @Test
    public void writer(){
        String path = "d:\\demo\\test\\note.txt";
        FileWriter fileWriter = null;
        char[] chars = {'H','e','l','l','o',',','H','o','r','l','d','!'};

        try {
            fileWriter = new FileWriter(path/*,true*/); 
            fileWriter.write('h');
            fileWriter.write(chars);
            fileWriter.write("不经历风雨,怎能见彩虹");
            fileWriter.write("锄禾日当午,汗滴禾下土",0,5);
            fileWriter.write(chars,0,5);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            try {
                fileWriter.close();
                //fileWriter.flush();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值