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 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基本类似

OutputStream.png

字符流

Reader

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
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 摘要 Java I/O是Java技术体系中非常基础的部分,它是学习Java NIO的基础。而深入理解Java NI...
    biakia阅读 12,252评论 7 81
  • 标准输入输出,文件的操作,网络上的数据流,字符串流,对象流,zip文件流等等,java中将输入输出抽象称为流,就好...
    navy_legend阅读 4,062评论 0 0
  • Java中I/O操作主要是指使用Java进行输入,输出操作. Java所有的I/O机制都是基于数据流进行输入输出,...
    cmlong_阅读 3,437评论 0 4
  • 字节流 InputStream 输入字节流 OutputStream 输出字节流 输入字节流----InputSt...
    向日花开阅读 7,057评论 0 4
  • Java IO整理 参考文献一:http://www.cnblogs.com/lich/tag/java%20IO...
    数独题阅读 3,558评论 0 0

友情链接更多精彩内容