Java-IO基础类回忆

好记性不如烂笔头,就拿Java IO来说吧,这部分的基础类我大学都已经学过一遍了,但是现在忘记的差不多了,所以准备写一篇博客,讲这些东西都回忆一下,并且整理一下。

首先借用网上的一张图:

纵向分为字节流和字符流.横向分为针对读写进行划分

在这幅图中那些非常基本的也就不提了,就提一下需要注意的几个类。

1.BufferedXXX 缓冲 无论是读还是写,字符还是字节流都存在,主要是作为一个缓冲的作用,起到的作用是减少和操作系统的IO交互,减少性能消耗

2.PipedXXX  管道    管道也是存在这四个当中,管道的用法相当于我们使用的队列,你往其中塞入数据的话,那么从另一端就可以取出来,否则就会堵塞,下面使用字符流的输入流作为例子:

package com.hotusm.io.learn.string;

import java.io.PipedReader;
import java.io.PipedWriter;

/**
 * 字符流取出管道
 * 1.PipedReader(PipedWriter src, int pipeSize)  第一个参数为输入管道流 第二个参数为管道的大小
 * 如果没有第二个参数那么默认的管道大小为1024
 * 2.PipedReader() 没有参数的构造函数为还没初始化的状态  需要调用connect(PipedWriter src)
 * 3.read() 会进行堵塞 直到有数据流到达 然后在进行读取
 */
public class PipedReaderTest {

    public static void main(String[] args) throws Exception{
        testPipedReaderConnect();
    }
    public static void testPipedReaderConnect() throws Exception{
        PipedReader pipedReader=new PipedReader();
        final PipedWriter writer=new PipedWriter();
        //这种方式进行连接
        pipedReader.connect(writer);
        char[] buff=new char[10];
        new Thread(()->{
            try {
                //停留三秒钟之后
                Thread.sleep(3000);
                writer.write("hello piped");
            } catch (Exception e) {
                e.printStackTrace();
            }

        }).start();
        pipedReader.read(buff);
        System.out.println(buff);
    }

}

3.字符流中独有的InputStreamReader 和OutputStreamWriter 。 使用适配器模式将字节流适配成字符流,这样就可以将字节流作为字符流使用。

4.输入流中特有的PushbackXXX 看上图种都是继承自XXXFilter ,它们都是=使用了装饰模式为读取的时候增加了回退的功能.下面使用字符形式展示其作用:

package com.hotusm.io.learn.string;

import java.io.CharArrayReader;
import java.io.PushbackReader;

/**
 * PushbackReader 能够将流或者字符进行回推到 缓冲区中. 1.PushbackReader(Reader reader,int size)
 * size: 每一次的read()的个数 ,默认是1 同时也是缓冲区的大小 2.unread()重载方法
 * 将一个或者多个的字符回推到缓冲区中,位置就是上一次读过的结尾 比如 abcd 读到c 现在推出gf 那么就是为 abcgfd 下次读的话 就会从
 * gf开始读 3.skip(long size) 跳过size 个字符
 */
public class FilterReaderAndPushbackReaderTest {

    public static void main(String[] args) {
        testFilterReaderUnreadSingleChar();
        System.out.println();
        testFilterReaderUnreadMutilChar();
        testFilterReaderSkip();
    }

    /**
     * 输出:abcCd
     */
    public static void testFilterReaderUnreadSingleChar() {
        String str = "abcd";
        try (CharArrayReader charArrayReader = new CharArrayReader(str.toCharArray());
                PushbackReader pushbackReader = new PushbackReader(charArrayReader);) {
            int c;
            while ((c = pushbackReader.read()) != -1) {
                System.out.print((char) c);
                // unread()的用法 将字符给回推到缓冲区中
                if (c == ‘c‘) {
                    pushbackReader.unread(‘C‘);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 输出:abcdefFUCgUC
     */
    public static void testFilterReaderUnreadMutilChar() {
        String str = "abcdefg";
        try (CharArrayReader charArrayReader = new CharArrayReader(str.toCharArray());
                PushbackReader pushbackReader = new PushbackReader(charArrayReader, 3);) {
            char[] byteArr = new char[3];
            // read方法会一直读入构造函数中第二个参数中的数量的字符
            while ((pushbackReader.read(byteArr)) != -1) {
                System.out.print(byteArr);
                // unread()的用法 将字符给回推到缓冲区中
                if (new String(byteArr).equals("def")) {
                    // 推回的不能大于缓冲区的 缓冲区就是我们构造函数的第二个参数
                    pushbackReader.unread("FUC".toCharArray());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 输出:abcfg
     */
    public static void testFilterReaderSkip() {
        String str = "abcdefg";
        try (CharArrayReader charArrayReader = new CharArrayReader(str.toCharArray());
                PushbackReader pushbackReader = new PushbackReader(charArrayReader, 3);) {
            char[] byteArr = new char[3];
            // read方法会一直读入构造函数中第二个参数中的
            while ((pushbackReader.read(byteArr)) != -1) {
                System.out.print(byteArr);
                //这里是重点!!!
                pushbackReader.skip(2L);
                byteArr = new char[3];
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

5.输出流中特有的两个PrintWriter和PrintStream,和前面不同的是,这两个除了一个是字符一个是字节之外,还有其他的不同点.它们也要一些相似点.下面一一来展示。

当我们使用PrintWriter的时候,但我们设置了能够自动刷新的话,那么只有在println,printf,format方法调用的时候才会起作用,这点和字节流的PrintStream是不同的。下面是源码中的描述:

* <p> Unlike the {@link PrintStream} class, if automatic flushing is enabled
 * it will be done only when one of the <tt>println</tt>, <tt>printf</tt>, or
 * <tt>format</tt> methods is invoked, rather than whenever a newline character
 * happens to be output.  These methods use the platform‘s own notion of line
 * separator rather than the newline character.

而PrintStream是是要调用了println或者是字符中进行了换行(‘\n‘)就会自动的刷新,这是和字符流中的不同点。源码中这样描述:

 <code>PrintStream</code> can be created so as to flush
 * automatically; this means that the <code>flush</code> method is
 * automatically invoked after a byte array is written, one of the
 * <code>println</code> methods is invoked, or a newline character or byte
 * (<code>‘\n‘</code>) is written.

参考: http://www.cnblogs.com/oubo/archive/2012/01/06/2394638.html

时间: 2024-11-03 21:58:13

Java-IO基础类回忆的相关文章

[Java] Java IO

Java IO 是 Java 的一套 API, 用于读入和写出数据(输入和输出).Java IO API 位于 java.io package.实际上 java.io package 没有解决所有的输入输出情况,例如,web 页面没有包含在 Java IO package 里面,而是由 Java 企业版本的 servlet 和 HTTP package 处理. Java IO package 关注文件.网络流(Network Stream), 内存缓冲区(internal memory buff

java IO流详解(一)

从本篇博文开始,详细讲解JAVA IO流的基本操作,力求每一个例子都给大家一个DEMO,在最终完成的时候,我会贴出最终的源码,方便大家交流学习. 上一篇博文中转载了大神的博文和图片,非常好! 文章链接如下:Java IO流 下面一个个的用实例进行讲解每个IO流的基本用法. 1 File文件 public static void main(String[] args) throws IOException { File file = new File("."); myPrint(file

java IO之输入流——InputStream

java的基本输入流是java.io.InputStream,该抽象类定义了输入流的基本输入操作方法,实现自该抽象类的子类都有定义自己的数据源,例如ByteArrayInputStream的构造函数指定了ByteArrayInputStream输入流的数据源必须是一个字符数组.这就可以有多种不同的数据源,包括:字符数组.String对象.文件."管道".一个由其他种类的流组成的序列... 1 public ByteArrayInputStream(byte buf[]) {} 2 3

Hive报错 Failed with exception java.io.IOException:java.lang.IllegalArgumentException: java.net.URISyntaxException: Relative path in absolute URI: ${system:user.name%7D

报错信息如下 Failed with exception java.io.IOException:java.lang.IllegalArgumentException: java.net.URISyntaxException: Relative path in absolute URI: ${system:user.name%7D 解决方法: 编辑 hive-site.xml 文件,添加下边的属性 <property> <name>system:java.io.tmpdir<

java.io.IOException: No space left on device 错误

今天碰到比较奇怪的问题: 7/05/14 19:20:24 INFO util.Utils: Fetching http://192.168.31.160:33039/jars/spark_study_java-0.0.1-SNAPSHOT-jar-with-dependencies.jar to /tmp/spark-446068a4-aaa4-4277-b009-908bf0d4ecac/executor-dcc3175b-7d19-4485-81e1-bf31a83a66b4/spark-

【java】io流之字节输入流:java.io.InputStream类及子类java.io.FileInputStream

1 package 文件操作; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.IOException; 6 import java.io.InputStream; 7 8 public class TestInputStream { 9 public static void main(String[] args) throws IOException { 10 File file=new F

java io 学习

1,io 体系 在整个Java.io包中最重要的就是5个类和一个接口.5个类指的是File.OutputStream.InputStream.Writer.Reader:一个接口指的是Serializable.掌握了这些IO的核心操作那么对于Java中的IO体系也就有了一个初步的认识了. Java.io包中定义了多个流类型类实现输入输出的功能,从不同的角度可以分为: ~按照数据流方向的不同可以分为输入流和输出流. ~按照按照数据处理单位的不同可以分为字节流和字符流. 如下几张图可以直观的描述io

Java IO流 探险

Java的IO流使用了一种装饰器设计模式,它将IO流分为底层节点流和上层处理流.本篇重点在如何访问文件与目录.如何以二进制格式和文本格式来读写数据.对象序列化机制.还有Java7的"NIO.2". 装饰设计模式:当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供加强功能.那么自定义的该类称为装饰类. 装饰类通常会通过构造方法接收被装饰的对象.并基于被装饰的对象的功能,提供更强的功能. IO的方式通常分为:BIO(同步阻塞).NIO(同步非阻塞).AIO

Play生产模式下java.io.FileNotFoundException那点事

之前”用Scala+Play构建地理数据查询接口”那篇文章里,用到的数据是json格式的文本文件area.json,存放在conf/jsons文件夹下.最开始是放在public/文件夹下,在线上准生产模式下运行: activator dist 得到mosquito-1.0.zip压缩包,解压后: 去/bin目录下运行mosquito脚本报错: java.io.FileNotFoundException 然后就去解压的mosquito-1.0/看发现并没有public文件夹,由此可见public文