Java流(IO流)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/anticlql/article/details/75402580

IO流

Java流式输入输出原理
在Java程序中,对于数据的输入输出操作以流的方式进行,J2SDK提供了各种各样的“流”类,用以获取不同种类的数据,程序中通过标准的方法输入或者输出数据

输入/输出流的分类

Java.io包中定义了多个流类型(类或抽象类)来实现输入/输出功能
按照数据流的方向不同可分为输入流输出流(在程序的角度看)
按照数据处理单位不同可分为字节流字符流
按照功能不同可以分为节点流处理流

J2SDK所提供的所有流类型位于包Java.io内都分别继承自一下四中抽象流类型

字节流 字符流
输入流 Inputstream Reader
输出流 Outoutstream Writer

节点流和处理流
节点流为可以从一个特定的数据源(节点)读写数据
处理流是“连接”在医讯在的流(节点流或者处理流)之上,通过对数据的处理为程序提供更为强大的读写功能

InputStream

继承自InputStream的流都是用于向程序中输入数据,且数据的单位为字节(8 bit)
如下图(深色为节点流,浅色为处理流)
这里写图片描述

InputStream基本方法
读取一个字节并以整数的形式返回(0~255)如果返回-1则已到输入流的末尾 int read() throws IOException

读取一系列字节并存储到一个数组buffer,返回实际读取的字节数,如果读取已到输入流的末尾返回-1
Int read(byte[]buffer) throws IOException

读取length个字节并存储到一个字节数组buffer,从length位置开始,返回实际读取的字节数,如果读取前已到输入流的末尾返回-1
Int read(byte[] buffer,int offset , int length) throws IOException

关闭流释放内存资源 void close() throws IOException

跳过n个字节不读,返回实际跳过的字节数 long skip(long n) throws IOException

OutputStream

继承自OutputStream的流适用于程序中输入数据,且数据的单位为字节(8 bit)
如下图(深色为节点流,浅色为处理流)
这里写图片描述

OutputStream基本方法
向输出流中写入一个字节数据,该字节数据为参数b的低8位
void write(int b) throws IOException

将一个字节类型的数组中的数据写入输入流
void write(byte[] b) throws IOException

将一个字节类型的数组中的指定位置(off)开始len个字节写入到输出流
void write(byte[] b,int off,int len) throws IOException

关闭流释放内存资源
void close() throws IOException

将输入流中缓冲的数据全部写出到目的地
void flush() throws IOException

Reader

继承自Reader的流都是用于向程序中输入数据,且数据的单位为字符(16 bit)
如下图(深色为节点流,浅色为处理流)
这里写图片描述

Reader的基本方法
读取一个字符并以整数的形式返回(0~255)如果返回-1则已到输入流的末尾
int read() throws IOException

读取一系列字节并存储到一个数组buffer,返回实际读取的字节数,如果读取已到输入流的末尾返回-1
Int read(char[] buffer) throws IOException

读取length个字符并存储到一个字节数组buffer,从length位置开始,返回实际读取的字符数,如果读取前已到输入流的末尾返回-1
Int read(char[ ] buffer,int offset , int length) throws IOException

关闭流释放内存资源 void close() throws IOException

跳过n个字符不读,返回实际跳过的字节数 long skip(long n) throws

Writer

继承自Writer的流都是用于程序中输出数据,且数据的单位为字符(16 bit)
如下图(深色为节点流,浅色为处理流)
这里写图片描述

Writer的基本方法
向输出流中写入一个字符数据,该字符数据为参数b的低16位
void write(int b) throws IOException

将一个字符类型的数组中的数据写入输入流
void write(char[] b) throws IOException

将一个字符类型的数组中的指定位置(off)开始len个字节写入到输出流
void write(char[] b,int off,int len) throws IOException

将一个字符串中的字符写入到输出流
void write(String string) throws IOException

将一个字符串从offset开始的length个字符写入带输出流
void write(String string,int offset,int length) throws IOException

关闭流释放内存资源
void close() throws IOException

将输入流中缓冲的数据全部写出到目的地
void flush() throws IOException

节点流类型

节点流为可以从一个特定的数据源(节点)读写数据

类型 字符流 字节流
File(文件) FileReader、 FileWriter FileInputStream、 FileOutPutStream
Memory Array CharArrayReader CharArrayWriter ByteArrayInputStream ByteArrayOutputStream
Memory String String Reader、String Writer ————–
Pipe(管道) PipedReader、PipedWriter PipedInputStream、PipedOutputStream

字节流举例,通过FileInputStream、 FileOutPutStream完成文件复制

public class TestFileStream {

    public static void main(String[] args) {
        //文件中有文字时将无法识别
        FileInputStream in;
        FileOutputStream out;
        int b = 0;

        try {
            in = new FileInputStream("d:\\java\\Hello.java");
            //当文件中没有Out.java这个文件时,会自动创建
            out = new FileOutputStream("d:\\java\\Out.java");

            while((b = in.read()) != -1){
                out.write(b);
            }
            in.close();
            out.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }   
        System.out.print("文件已复制!");
    }

}

FileReader、FileWriter类似于FileInputStream、 FileOutPutStream,但利用前者可以完美的打印出中文

处理流类型

前面提到处理流是“连接”在医讯在的流(节点流或者处理流)之上,通过对数据的处理为程序提供更为强大的读写功能

处理类型 字符流 字节流
Buffering BufferedReader、BufferedWriter BufferedInputStream、BufferedOutputStream
Filtering FilterReader、FilterWriter FilterInputStream、FilterOutputStream
Converting between bytes and character IntputStreamReader OutputStreamReader
Object Serialization ObjectIntputStream、ObjectOutputStream
Data conversion DataIntputStream、DataOutputStream
Counting LineNumberReader LineNumberInputStream
Peeking ahead PusbackReader PushbackInputStream
Printing PrintWriter PrintStream

缓冲流

缓冲流要“套接”在相应的节点流上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法
J2SDK提供了四中缓冲流,其常用的构造方法为

BufferedReader(Read in)
BufferedReader(Read in, int sz) sz为自定义缓存区的大小
BufferedWriter (Write out)
BufferedWriter (Write out,int sz)
BufferedInputStream(InputStream in)
BufferedInputStream(InputStream in,int size)
BufferedOutputStream(OutputStream out)
BufferedOutputStream(OutputStream out,int size)

  • 缓冲输入流支持其父类的mark和reset方法
  • BufferedReader提供了readLine()方法用于读一行字符串(以\r或者\n分隔)
  • BufferedWriter提供了newLine()方法用于写入一行分隔符
  • 对于输出的缓冲流,写出的数据会现在内存中缓存,使用flush方法将会使内存中的数据立刻写出
    BufferedReader、BufferedWriter举例
public class TestBuffered {

    public static void main(String[] args) {
        try {
            BufferedWriter bw = new BufferedWriter(new FileWriter("d:\\java\\File\\Hello.java"));
            BufferedReader br = new BufferedReader(new FileReader("d:\\java\\File\\Hello.java"));

            String s = null;
            //向文件中写了100行0~1的随机数
            for(int i = 0;i<100;i++){
                s = String.valueOf(Math.random());
                bw.write(s);
                bw.newLine();
            }
            bw.flush();
            //打印数据
            while((s=br.readLine()) != null){
                System.out.println(s);
            }
            //关闭流
            bw.close();
            br.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            //运行结果不再给出
        }
    }
}

转换流

InputStreamReader和OutputStreamWriter用于字节数据到字符数据之间的转换
InputStreamReader需要和InputStream“套接”
OutputStreamWriter需要和OutputStream“套接”
并且转换流在构造时可以指定其编码集合,例如:
InputStream isr = new InputStreamReader(System.in,”ISO8859_1”)
InputStreamReader、OutputStreamWriter举例

public class TestTransform {

    public static void main(String[] args) {
        try {
            //FileOutputStream的构造方法中后又一个true,添加上代表文件中内容不会被覆盖而是添加
            OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d:\\java\\File\\Hello.java",true),"ISO8859_1");
            osw.write("123456789");
        } catch (FileNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


        //System.in是标准的输入流,是InputStream的一个子类,完成了转换
        InputStreamReader isr = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(isr);
        String s = null;

        try {
            while((s = br.readLine()) !=null){
                if (s.equalsIgnoreCase("exit"))
                    break;
                System.out.println(s.toUpperCase());
            }
            isr.close();
            br.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

数据流

DataInputStream和DataOutputStream分别继承自InputStream和OutputStream,它属于处理流,分别需要“套接”在InputStream和OutputStream类型的节点流上
DataInputStream和DataOutputStream提供了可以存取与机器无关的Java原始类型数据(如int、double等)的方法

DataInputStream和DataOutputStream的构造方法:
DataInputStream (InputStream in)
DataOutputStream (OUtputStream out)
数据流举例:

import java.io.*;

public class TestDataIO {

    public static void main(String[] args) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(baos);

        try {
            dos.writeDouble(Math.random());
            dos.writeBoolean(true);
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            //可供读的字节
            System.out.println(bais.available());
            DataInputStream dis = new DataInputStream(bais);
            //先存先出
            System.out.println(dis.readDouble());
            System.out.println(dis.readBoolean());
            dos.close();
            dis.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

运行结果:

9
0.20684497834468674
true

Print流

PrintWriter和PrintStream都属于流分别针对字符和字节
PrintWriter和PrintStream提供了重载的print、println方法用于多种数据类型的输出
PrintWriter和PrintStream输出操作不会抛出异常,用户通过检测错误状态获取错误信息
PrintWriter和PrintStream有自动的flush功能

PrintWriter常用方法
PrintWriter(Write out)
PrintWriter(Write out,boolean autoFlush)
PrintWriter(OutputStream out)
PrintWriter(OutprintStream out,boolean autoFlush)
PrintStream(OutprintStream out)
PrintStream(OutprintStream out,boolean autoFlush)

Print流举例

import java.io.*;
import java.util.Date;

public class TestPrintStream {

    public static void main(String[] args) {
        String s = null;
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        try {
            FileWriter fw = new FileWriter("d:\\java\\File\\TestPrintStream.txt",true);
            PrintWriter log = new PrintWriter(fw);
            while((s=br.readLine()) != null){
                if(s.equalsIgnoreCase("exit"))
                    break;
                System.out.println(s.toUpperCase());
                log.println("-------------");
                log.println(s.toUpperCase());
                //可以显式的调用
                log.flush();
            }
            log.println("===="+new Date()+"=====");
            log.flush();
            log.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

Object流

直接将Object写入或读出
transient关键字
serializable接口
externalizable接口 自身控制序列化过程,是serializable的一个子接口
Object流举例:

import java.io.*;

public class TestObjectIO {

    public static void main(String[] args) throws Exception {
        T t = new T();
        t.j = 12;

        FileOutputStream fos = new FileOutputStream("d:\\java\\File\\a.java");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(t);
        oos.flush();
        oos.close();

        FileInputStream fis = new FileInputStream("d:\\java\\File\\a.java");
        ObjectInputStream ois = new ObjectInputStream(fis);
        T tRead = (T) ois.readObject();
        System.out.println(tRead.i + " " + tRead.j + " " + tRead.k + " "
                + tRead.b);

    }

}

class T implements Serializable{
    int i = 8;
    int j = 15;
    //加上transient关键字后在序列化时不于考虑,序列化时不会往硬盘上写
    transient int k = 10;
    double b = 2.3;
}

运行结果8 12 0 2.3

猜你喜欢

转载自blog.csdn.net/anticlql/article/details/75402580