欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java I/O知识点总结

程序员文章站 2024-03-03 19:25:28
...

I/O 字节、字符流接口简介

说明
File 文件类,代表一个特定文件信息,或代表一个目录下的一组文件, 常用方法getName、length、canRead、canWrite、getPath、exists、list、mkdirs、delete等方法
InputStream 字节输入流接口,表示从不同数据源产生输入的类
OutputStream 字节输出流接口,表示数据输出的目标
Reader 字符输入流接口
Writer 字符输出流接口

字符流是对文本内容高效操作的流对象。本质是基于字节流读取时,根据字符编码转化对应的文本内容。

File类使用实例

// 运用File.list的策略模式,返回文件名小于5字符的文件组
public class DirList {
    public static void main(String[] args) {
        File path = new File(".");
        System.out.println("绝对路径: " + path.getAbsolutePath());
        System.out.println("可读写: " + path.canRead() + " " + path.canWrite());
        System.out.println("文件名: " + path.getName());
        System.out.println("最后修改时间: " + path.lastModified());
        String[] list = path.list(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return name.length() < 5 ? true : false;
            }
        });
        for (String s : list) {
            System.out.println(s);
        }
    }
}

字节流结构图

java I/O知识点总结

字节输入流

功能 构造参数
InputStream 抽象类,是所有的输入字节流的父类
ByteArrayInputStream 从缓冲区(内存)中读取数据 byte[]
FileInputStream 从本地文件中读取数据 File对象、文件名字符串、或FileDescriptor对象
FilterInputStream 抽象类,作为“装饰器”的接口,为InputStream类提供更丰富的功能
BufferedInputStream FilterInputStream子类,使用缓冲区进行读取数据 InputStream对象,可指定缓冲区大小
DataInputStream FilterInputStream子类,与DataOutputStream搭配使用,可按照要求读取基本数据类型(int、char、long等) InputStream对象
PushbackInputStream FilterInputStream子类,查看最后一个字节,不满意就放入缓冲区。主要用在编译器的语法、词法分析部分 InputStream对象
LineNumberInputStream @Deprecated已弃 FilterInputStream子类,可以跟踪流中的行号 InputStream对象
PipedInputStream 多线程之间管道通信 PipedOutputStream对象
ObjectInputStream ”装饰流”,用于java序列化支持 InputStream对象
SequenceInputStream 一个工具类,将两个或者多个输入流当成一个输入流依次读取 两个InputStream对象、或一个容纳InputStream对象的容器Enumeration
StringBufferInputStream @Deprecated已弃 从字符串中读取数据,底层实现使用StringBuffer String对象

字节输出流

功能 构造参数
OutputStream 抽象类,是所有的输出字节流的父类
ByteArrayOutputStream 将流信息写入向缓冲区(内存byte数组) byte[],大小可选
FileOutputStream 将流信息写入文件 File对象、文件名字符串、或FileDescriptor对象
FileOutputStream 抽象类,作为“装饰器”的接口,为OutputStream类提供更丰富的功能
BufferedOutputStream FilterOutputStream子类,使用缓冲区进行写入,避免每次发送数据时都要进行实际的写操作(只有缓冲区满时才进行实际的写入操作),flush()清空缓冲区 OutputStream对象,可指定缓冲区大小
DataOutputStream FilterOutputStream子类,与DataInputStream搭配使用,可以向流中写入基本的类型数据(int、char、long等) InputStream对象
PrintStream FilterOutputStream子类,用于产生格式化的输出,其中DataOutputStream处理数据存储,PrintStream处理显示,或者FileInputStream 写入数据,本身内部实现还是带缓冲的。本质上是对其它流的综合运用的一个工具,System.out和System.err就是PrintStream的实例 OutputStream对象
PipedOutputStream 任何写入其中的信息自动作为相关PipedInputStream的输出,实现管道概念 PipedInputStream对象
ObjectOutputStream ”装饰流”,用于java序列化支持 OutputStream对象

字节流使用实例

// An highlighted block
public class StoringAndRecoveringData {
    public static void main(String[] args)
    throws IOException {
        DataOutputStream out = new DataOutputStream(    // 搭配装饰器,支持基本类型的操作
                new BufferedOutputStream(      // 使用缓存装饰器
                        new FileOutputStream(    // 以文件流为目标写入文件
                                new File("data.txt").getAbsoluteFile())));  //  getAbsoluteFile()的作用是在报错时,可显示报错文件的绝对路径
        out.writeDouble(3.14159);
        out.writeUTF("That was pi");
        out.close();
        DataInputStream in = new DataInputStream( // 与DataOutputStream搭配,支持基本类型的操作
                new BufferedInputStream(   // 使用缓存装饰器
                        new FileInputStream(   // 从本地文件数据源读取数据
                                new File("data.txt").getAbsoluteFile())));
        System.out.println(in.readDouble());
        System.out.println(in.readUTF());
        in.close();
    }
}
/* output:
3.14159
That was pi
*/

字符流结构图

java I/O知识点总结

字符输入流

功能 构造参数
Reader 抽象类,是所有的输入字符流的父类
CharArrayReader 从char[]中读取数据 char[]
StringReader 从String中读取数据 String对象
InputStreamReader InputStream到Reader转换的桥梁 InputStream对象
FileReader InputStreamReader的子类,以字符流读取文件信息常用工具类,将FileInputStream 转变为Reader 的方法 File对象、文件名字符串、或FileDescriptor对象
PipedReader 多线程之间管道通信 PipedWriter对象
FilterReader 抽象类,作为“装饰器”的接口,为Reader类提供更丰富的功能
PushbackReader FilterReader子类,对Reader对象进行装饰,会增加一个行号 Reader对象
BufferedReader 装饰Reader对象,使用BufferedReader.readLine()是有效的读取行操作的方法 Reader对象
LineNumberReader BufferedReader子类,对Reader对象进行装饰,可获取行信息 Reader对象

字符输出流

功能 构造参数
Writer 抽象类,是所有的输出字符流的父类
CharArrayWriter 向char[]中写入数据 char[]
StringWriter 向String中写入数据 String对象
OutputStreamWriter OutputStream到Writer转换的桥梁 OutputStream对象
FileWriter OutputStreamWriter的子类,向文件写入字符流的常用工具类,将FileOutputStream 转变为Writer 的方法 File对象、文件名字符串、或FileDescriptor对象
PipedWriter 多线程之间管道通信 PipedReader对象
FilterWriter 抽象类,作为“装饰器”的接口,为Writer类提供更丰富的功能,没子类
BufferedWriter 装饰Writer对象,提供缓冲功能 Writer对象
PrintWriter 与PrintStream类似 Writer对象

InputStreamReader可以把InputStream转换为Reader
OutputStreamWriter可以把OutputStream转换为Writer

字符流使用实例

public class BasicFileOutput {
    static String file = "BasicFileOutput.out";
    public static void main(String[] args)
    throws IOException {
        BufferedReader in = new BufferedReader(
                new StringReader("hello world"));
        PrintWriter out = new PrintWriter(
                new BufferedWriter(new FileWriter(file)));
        int lineCout = 1;
        String s;
        while ((s = in.readLine()) != null) {
            out.println(lineCout++ + ": " + s);
        }
        out.close();
    }
}

RandomAccessFile类

RandomAccessFile封装了字节流,同时还封装了一个缓冲区(字符数组),可以认为他是DataInputStream和DataOutputStream的整合。 该对象特点:

  • 该对象只能操作文件,所以构造函数接收两种类型的参数:a.字符串文件路径;b.File对象。
  • 该对象既可以对文件进行读操作,也能进行写操作,在进行对象实例化时可指定操作模式(r、rw)。

注意:该对象在实例化时,如果操作的文件不存在,会自动创建;如果文件存在,写数据未指定位置,会从头开始写,即覆盖原有的内容。 可以用于多线程下载或多个线程同时写数据到文件。

RandomAccessFile使用实例

// 比较nio与普通io的速度
public class MapperIO {
    private static int numOfInts = 400000;
    private static int numOfUbuffInts = 200000;
    private abstract static class Tester {
        private String name;
        public Tester(String name) {
            this.name = name;
        }
        public void runTest() {
            System.out.print(name + ": ");
            try {
                long start = System.nanoTime();
                test();
                double duration = System.nanoTime() - start;
                System.out.format("%.2f\n", duration/1.0e9);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        public abstract void test() throws IOException;
    }
    private static  Tester[] tests = {
            new Tester("Stream Write") {
                @Override
                public void test() throws IOException {
                    DataOutputStream dos = new DataOutputStream(
                            new BufferedOutputStream(
                                    new FileOutputStream(new File("temp.tmp"))));
                    for(int i = 0; i < numOfInts; i++) {
                        dos.writeInt(i);
                    }
                    dos.close();
                }
            } ,  new Tester("Mapped Write") {
                @Override
                public void test() throws IOException {
                    FileChannel fc =
                            new RandomAccessFile("temp.tmp", "rw").getChannel();
                    IntBuffer ib = fc.map(FileChannel.MapMode.READ_WRITE, 0, fc.size()).asIntBuffer();
                    for(int i = 0; i < numOfInts; i++) {
                        ib.put(i);
                    }
                    fc.close();
                }
            },
            new Tester("Stream Read") {
                @Override
                public void test() throws IOException {
                    DataInputStream dis = new DataInputStream(
                            new BufferedInputStream(new FileInputStream("temp.tmp")));
                    for(int i = 0; i < numOfInts; i++) {
                        dis.readInt();
                    }
                    dis.close();
                }
            },  new Tester("Mapped Read") {
                @Override
                public void test() throws IOException {
                    FileChannel fc =
                            new RandomAccessFile("temp.tmp", "rw").getChannel();
                    IntBuffer ib = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()).asIntBuffer();
                    while (ib.hasRemaining()){
                        ib.get();
                    }
                    fc.close();
                }
            },  new Tester("System Read/Write") {
                @Override
                public void test() throws IOException {
                    RandomAccessFile fc =
                            new RandomAccessFile("temp.tmp", "rw");
                    fc.writeInt('a');
                    for(int i = 0; i < numOfUbuffInts; i++) {
                        fc.seek(i*4);
                        fc.writeInt(fc.readInt());
                    }
                    fc.close();
                }
            },
            new Tester("Mapped Read/Write") {
                @Override
                public void test() throws IOException {
                    FileChannel fc =
                            new RandomAccessFile("temp.tmp", "rw").getChannel();
                    IntBuffer ib = fc.map(FileChannel.MapMode.READ_WRITE, 0, fc.size()).asIntBuffer();
                    ib.put('b');
                    for(int i = 1; i < numOfUbuffInts; i++) {
                        ib.put(ib.get(i-1));
                    }
                    fc.close();
                }
            }
    };
    public static void main(String[] args) {
        // 测试文件映射和IO操作性能
        for (Tester test : tests) {
            test.runTest();
        }
    }
}
/*output:
Stream Write: 0.03
Mapped Write: 0.01
Stream Read: 0.04
Mapped Read: 0.01
System Read/Write: 2.46
Mapped Read/Write: 0.01
* */

序列化实例

java序列化支持有ObjectOutputStream和ObjectInputStream支持

public class Logon implements Serializable {
    private Date date = new Date();
    private String username;
    private transient String password;  // transient关键之表示序列化时不保存该字段信息
    public Logon(String name, String pwd) {
        username = name;
        password = pwd;
    }
    @Override
    public String toString() {
        return "logon info: \n   username: " + username +
                "\n   date: " + date + "\n  password: " + password;
    }

    public static void main(String[] args) throws Exception {
        Logon a = new Logon("Hulk", "myLittlePony");
        System.out.println("logon a = " + a) ;
        ObjectOutputStream o = new ObjectOutputStream(
                new FileOutputStream("Logon.out"));
        o.writeObject(a);
        o.close();
        TimeUnit.SECONDS.sleep(3);
        ObjectInputStream in = new ObjectInputStream(
                new FileInputStream("Logon.out"));
        System.out.println("Recovering object at " + new Date());
        a = (Logon) in.readObject();
        System.out.println("logon a = " + a) ;
    }
}
/*output:
logon a = logon info: 
   username: Hulk
   date: Thu Jan 31 17:02:54 CST 2019
  password: myLittlePony
Recovering object at Thu Jan 31 17:02:57 CST 2019
logon a = logon info: 
   username: Hulk
   date: Thu Jan 31 17:02:54 CST 2019
  password: null
*/
  • 如果需要特定的序列化规则,可以实现Externalizable接口,根据自定义的规则重写writeExternal(ObjectOutput)和 readExternal(ObjectInput)方法。

详细使用方式请查看jdk文档

——————>nio博客地址<——————



、﹗∕
— 〇 -
╱︱ ヽ
但行好事、莫问前程!
>.freerme[https://blog.csdn.net/freerme]
_________________ *_*______
____________
相关标签: java IO系统 IO