java io

永远看不懂的Java IO

有一件非常蛋疼的事情,每次准备面试去看Java IO的时候,心里总是无数只草泥马跑过- -
最近心血来潮在看Java编程思想,我简直越看越。
姑且把自己的理解先记下来,有空慢慢补。

基本结构

众所周知,两种:基于字节和基于字符。

字节流:通过8位字节来实现输入输出,处理的是字节(byte)和字节数组。适用于音频文件,图片,歌曲等。
所有的字节流类都继承自InputStream和OutputStream。

字符流:处理的单元为两个字节的Unicode字符,分别操作字符(char),字符数组或者字符串(String)。(字符流由Java虚拟机将字节转化为2个字节地Unicode字符而成,所以对文本的支持比较好)。
所有的字符流都继承自Reader和Writer。

 注意:所有文件的储存是都是字节(byte)的储存,在磁盘上保留的并不是文件的字符而是先把字符编码成字节,再储存这些字节到磁盘。在读取文件(特别是文本文件)时,也是一个字节一个字节地读取以形成字节序列。

在两者之间还会有一些转换,这时候可以用InputStreamReader(从InputStream字节流转换为Reader的字符流)。这时候需要制定字符编码,否则会默认采用系统的编码,出现乱码。

字节流

InputStream

java io_第1张图片
java inputstream.png

其中用的比较多的FileInputStream和BufferedInputStream

  • FileInputStream: 以字节方式读取file.

三种构造函数

// construct by file name
FileInputStream in = new FileInputStream("/Users/lulei/Desktop/test.txt");

File file = new File("/Users/lulei/Desktop/test.txt");
// construct by file
in = new FileInputStream(file);

// construct by file descriptor
FileInputStream in2 = new FileInputStream(in.getFD());

使用方式

byte[] bytes = new byte[1024];
int temp, len = 0;
while ((temp = in.read())!= -1) {    
bytes[len] = (byte) temp;    
len++;
}
fs.close();
System.out.println(new String(bytes, 0, len));
  • ByteArrayInputStream 流的来源是一串字节数组
    构造函数
ByteArrayInputStream(byte[] buf);

ByteArrayInputStream(byte[] buf, int offset, int len);
  • ObjectInputStream 读取对象类型的数据,将一个序列化的对象通过底层字节输入流读取到程序中
    可以把inputstream包装到ObjectInputStream中,这样就可以直接读取对象了(这个对象必须要是serializable的)
ObjectInputStream input = new ObjectInputStream(new FileInputStream("object.data"));

MyClass object = (MyClass) input.readObject(); //etc.

input.close();
  • DataInputStream 继承自FilterInputStream,算是一个装饰类。可以返回一些基本类型,而不一定要是byte。
FileInputStream fs = new FileInputStream(file);
DataInputStream dataInputStream = new DataInputStream(fs);
dataInputStream.readInt();
  • BufferedInputStream 继承自FilterInputStream, 也是装饰类,可以起到一个缓冲的作用,防止每次都真正执行操作。
BufferedInputStream bis = new BufferedInputStream(fs);
bis.read();

OutputStream

OutputStream的结构与InputStream基本类似

java io_第2张图片
OutputStream.png

字符流

Reader

java io_第3张图片
Reader.png

Reader与InputStream的结构相似,但却有些不同。
比如,BufferedReader并未继承FilterReader。

一些典型的使用方法

  1. 缓冲输入文件 (BufferedReader)
public class BufferedInputFile {
  public static String read(String fileName) throws IOException {
    // reading input by lines
    BufferedReader in = new BufferedReader(new FileReader(fileName));
    StringBuilder sb = new StringBuilder();
    String s;
    while( ( s = in.readLine()) != null) {
        sb.append(s);
    }
    in.close();
    return sb.toString();
  }
}
  1. 从内存输入 (StringReader)
    下面的例子读取内存中的String,并且调用read(),每次读取一个字符
public class MemoryInput {
    public static void main(String[] args) {
        StringReader in = new StringReader(BufferedInputFile.read("test.txt"));
        int c;
        While ((c = in.read()) != -1) {
            System.out.print((char)c);
        }
    }
}
  1. 格式化的内存输入
    要读取格式化数据,可以使用DataInputStream, 它是一个面向字节的IO类
public class FormattedMemoryInput{
    public static void main(String[] args) {
        DataInputStream in = new DataInputStream(new ByteInputStream(BufferedInputFile.read("test.txt").getBytes());
        in.readByte(); // 返回的就是Byte
        in.readInt(); // 返回的就是int
    }
}

你可能感兴趣的:(java io)