JavaIO

2020-08-09  本文已影响0人  一个追寻者的故事
//组合输入流过滤器
val fin = FileInputStream("a.txt")
val din = DataInputStream(fin)
val res = din.readInt()

所有在Java.io中的类都将相对路径名解释为以用户工作目录开始。 工作目录可以通过这个来查看:
System.getProperty("user.dir")

不存在任何可靠的方式可以自动地探测字节流中所使用的字符编码方式,某些API方法让我们使用【默认字符集】,即计算机的操作系统首选的字符编码方式。我们应该总是明确指定编码方式。

//这个抽象类是所有实现了【基于字节】输入流的超类
public abstract class InputStream implements Closeable {
    /**
从输入流中读取下一字节数据,返回数据是int类型,区间值为 0 到 255。-1 代表到了输入流的结尾。这个方法将会被阻塞直到输入数据是可用,或者到了流的结尾,又或者抛出一个异常。
    */
    public abstract int read() throws IOException;
}
//这个抽象类是所有实现了【基于字节】输出流的超类
public abstract class OutputStream implements Closeable, Flushable {
    //将指定的字节写入输出流。参数是个int类型,取低8位,剩下的24位忽略
    public abstract void write(int b) throws IOException;
}
//基于从文件系统中读取文件的输入流。这个类从文件读取最原始的【字节】数组流,比如一个图片。如果从文件中读取【字符】流,可以考虑使用 FileReader
class FileInputStream extends InputStream{
  //从输入中读取一个字节的数据 (-1 到 255)
  public int read() throws IOException {
      return read0();
  }
  private native int read0() throws IOException;
}
// 组合过滤输入流。它通常包含其他的输入流作为数据基础来源。可能进行数据的转化或者提供额外的功能。以DataInputStream为例。这是装饰器模式的应用。
class FilterInputStream extends InputStream { 
    protected volatile InputStream in;
    protected FilterInputStream(InputStream in) {
        this.in = in;
    }
}
/** DataInputStream 可以让我们从它依赖的输入流中读取原始Java数据类型(机器无关)。所以我们知道 DataInputStream 的使用是要依赖于其它 输入流的。
*/
class DataInputStream extends FilterInputStream implements DataInput {
//基本类型:byte、short、char、int、long、float、String(readUTF)

//构造器
public DataInputStream(InputStream in)

//读取Int。依次从依赖的输入流中读取四个字节,然后组合成int
public final int readInt() throws IOException {
        int ch1 = in.read();
        int ch2 = in.read();
        int ch3 = in.read();
        int ch4 = in.read();
        if ((ch1 | ch2 | ch3 | ch4) < 0)
            throw new EOFException();
        return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
    }
}
// BufferedInputStream 给一个输入流提供更多的功能。 例如:缓存输入,支持mark、reset等。当BufferedInputStream被创建,内部会同时创建一个缓存数组。当执行read、skip方法,缓存可能需要被重新填充。mark 方法会在输入流中记录一个位置,reset 方法执行时,会让字节重新回到最近一次被mark的位置。
class BufferedInputStream extends FilterInputStream {}

//这是一个读取【基于字符】流的抽象类
public abstract class Reader implements Readable, Closeable {
    //从流中读取一个字符数组。这个方法会阻塞线程,直到输入是可用的,或者到了流的末尾,又或者抛出一个IO错误。
    abstract public int read(char cbuf[], int off, int len) throws IOException;
}
// InputStreamReader 是一个从 【字节流】到 【字符流】的桥梁。它读取【字节】然后按照指定的编码方式将字节解码成【字符】
public class InputStreamReader extends Reader {
    //读取一个字符。这个方法会从它所依赖的 【字符流】中读取一个或更多字节,然后转化成字符。
    public int read() throws IOException {}
}
// 方便的文件【字符】读取工具。实现很简单,其实就是构建了一个FileInputStream 传给 InputStreamReader
public class FileReader extends InputStreamReader {
    //构造器
    public FileReader(String fileName) throws FileNotFoundException {
        super(new FileInputStream(fileName));
    }
}
//写出到【字符】流的抽象类。
public abstract class Writer implements Appendable, Closeable, Flushable {
    ...
}
/**OutputStreamWriter 提供了一个桥梁:从【字符流】到【字节流】(因为最终需要编码成字节进行传递,这里的作用和 InputStreamReader作用相反。)字符最终通过特定的Charset编码成字节。 每当write()方法执行,将会触发编码转换器将字符转换成字节,同时会将字节缓存起来(不是立即写入它所依赖的outputStream)。考虑到效率,可以考虑将 OutputStreamWriter 包裹在一个 BufferedWriter中,从而避免频繁触发编码转换器。例如:
Writer out = new BufferedWriter(new OutputStreamWriter(System.out));
*/
public class OutputStreamWriter extends Writer {
    // 写入一个字符
    public void write(int c) throws IOException {
        se.write(c);
    }
}
//文件写入字符流。其实就是  OuputStreamWriter 和 FileOuputStream 的组合。
public class FileWriter extends OutputStreamWriter {}
/**将文本写入字符输出流。通过缓存字符可以提高写入的效率。可以指定缓存区大小,也可以接收默认大小,对大多数用途,默认值足够大。提供了newLine()方法,使用平台自己系统属性中定义的分隔符概念。 通常,Writer会立即将其输出发送到基础字符或字节流,除非需要立即输出,否则建议将其包装在BufferedWriter里。例如:FileWriter 、OutputStreamWriter。
PrintWriter out = new PrintWriter(new BufferedWriter(FileWriter("a.txt")))
*/
public class BufferedWriter extends Writer {
    private char cb[];
    private static int defaultCharBufferSize = 8192;
}
//将格式化的对象表示形式打印到文本输出流。 print、println、format、append
public class PrintWriter extends Writer {}
// PrintStream 给其它输出流添加额外功能。由PrintStream打印的所有字符都使用平台的默认字符编码转换为字节。 在需要写入字符而不是字节的情况下,应使用PrintWriter类。
public class PrintStream extends FilterOutputStream
    implements Appendable, Closeable{}

其实没分清楚 PrintWriter 和 PrintStream的区别,只是PrintWriter处理文本能力相对强一点。PrintStream也可以处理文本,也可以处理原生字节。

读取读取文本输入可以使用 BufferedReader。例如:
BufferedReader reader = new BufferReader(InputStreamReader(inputStream,Charsets.UTF_8))。 还有另外一个方式Scanner,可以从任何输入流中构建Scanner对象。 Scanner 可以按照某种解码方式读取字符、文本,还有读取数字等基本Java基本类型的方法。

上一篇 下一篇

猜你喜欢

热点阅读