美文网首页
Thinking in Java - Java-IO系统笔记

Thinking in Java - Java-IO系统笔记

作者: gb_QA_log | 来源:发表于2018-07-12 15:26 被阅读0次

title: Java-IO系统笔记
date: 2017-04-03 11:14:30
categories: Java
mathjax: false
tags: [Thinking in Java]


写在前面

之前因为忽然需要文件处理,查了下后发现觉得IO类结构不是很清晰。在阅读《Thinking in Java》关于这部分的介绍后,特在此记录。需要简单的文件读写请直接阅读典型输入使用方式典型输出使用方式部分。

输入

InputStream类

InputStream是用来表示从不同数据源产生输入的类,它有以下子类:

  • ByteArrayInputStream:从内存缓冲区
  • StringBufferInputStream:将String转为InputStream
  • FileInputStream:文件
  • PipedInputStream:管道化
  • SequenceInputStream:多个InputStream转为一个InputStream
  • FilterInputStream:作为装饰器的接口,为其他InputStream类提供有用功能。有以下子类:
    • DataInputStream:按照可移植方式从流中读取基本类型
    • BufferedInputStream :缓冲区
    • LineNumberInputStream :跟踪行号,getLineNumber()等方法
    • PushbackInputStream :通常作为编译器的扫描器,能将读到的最后一个字符回退T

InputStreamReader类 适配器

简单地说,InputStream和Reader的不同在于前者是字节,后者是字符操作。因此,字节到字符间的转换需要适配器。子类:

  • FileReader
new FileReader("eaxmple.txt") 
//查看源码,发现其实相当于,使用的是默认encoder
new InputStreamReader(new FileInputStream("eaxmple.txt"))

Reader类

子类:

  • FilterReader
    • PushbackReader
  • BufferedReader
    • LineNumberReader

典型输入使用方式

字符文本

File file = new File("example.txt");//最好检验存在
if (file.exists()) {
    try {
        FileInputStream stream = new FileInputStream(file);//InputSteam
        InputStreamReader adapter = new InputStreamReader(stream,"GBK");//适配器
        BufferedReader reader = new BufferedReader(adapter);//Reader
        String tmp = reader.readLine();//读到内存的例子
        reader.flush();//此处可省略
        reader.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

二进制文件

File file = new File("example.txt");
if (file.exists()) {
    try {
        FileInputStream stream = new FileInputStream(file);
        BufferedInputStream buffer = new BufferedInputStream(stream);
    } catch (IOException e) {
        e.printStackTrace();
    }
}
  • 在reader.readLine()等用完后,reader.flush()是将缓冲区的内容进行实际的IO操作,如果不需要多次flush刷新的话,可以省略。因为最后reader.close()时会自动调用flush方法。
  • FileInputStream可以传File,也可以传入String来构造。根据源码,传入String后仍旧是new File对象再构造FileInputStream。

输出

OutputStream类

子类:

  • ByteArrayOutputStream:放到在内存创建的缓冲区中
  • FileOutputStream:写到文件
  • PipedOutputStream:管道
  • FilterOutputStream:装饰器,为其他OutputStream提供有用功能
    • DataOutputStream:按照可移植方式向流中写入基本类型
    • PrintStream:产生格式化输出。内部实现用的是BufferedWriter,可以设置autoFlush
    • BufferedOutputStream:使用缓冲区

OutputStreamWriter类 适配器

继承Writer类,构造器接受OutputStream对象
子类:

  • FileWriter
new FileWriter("eaxmple.txt") 
//查看源码,发现其实相当于,使用的是默认encoder
new OutputStreamWriter(new FileOutputStream("eaxmple.txt"))

Writer类

子类:

  • FilterWriter
  • BufferedWriter
  • PrintWriter:格式化

典型输出使用方式

//字符文件
File file = new File("example.txt");
if (file.exists()) {
    try {
        FileOutputStream stream = new FileOutputStream(file);//OutputSteam
        OutputStreamWriter adapter = new OutputStreamWriter(stream,"GBK");//适配器
        BufferedWriter writer = new BufferedWriter(adapter);//Reader
        writer.write("test");
        writer.flush();//此处可省略
        writer.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
  • 在reader.readLine()等用完后,reader.flush()是将缓冲区的内容进行实际的IO操作,如果不需要多次flush刷新的话,可以省略。因为最后reader.close()时会自动调用flush方法。
  • PrintWriter的构造器除了和Writer子类一样能接受Writer对象,还接受OutputStream作为参数来构造。Java SE5之后还增加了一个构造器:
File file = new File("example.txt");
new PrintWriter(file)
//查看源码,发现其实相当于如下过程。只是为了少写点装饰过程的代码。
new PrintWriter(
    new BufferedWriter(
        new OutputStreamWriter(
            new FileOutputStream(file)))

RandomAccessFile

类似C语言中的fopen(),在nio中有新的处理方式,暂不详细看这个类。

文件读写实用工具

装饰器使得文件读写变得麻烦,PrintWriter简化了输出的过程。而自己也可以封装一些针对Text等常用文件的操作。

虽然PrintWriter可以对数据格式化,便于阅读。但是数据的存储还是建议用DataOutputStream写入,DataInputStream恢复:

//存储数据:写入文件
File file = new File("example.txt");
if (file.exists()) {
    try {
        FileOutputStream stream = new FileOutputStream(file);
        BufferedOutputStream buffer = new BufferedOutputStream(stream);
        DataOutputStream dataOutputStream = new DataOutputStream(buffer);
        dataOutputStream.writeUTF("That was pi");
        dataOutputStream.writeDouble(3.14159);
    } catch (IOException e) {
        e.printStackTrace();
    }
}
//恢复数据:从文件读出
File file = new File("example.txt");
if (file.exists()) {
    try {
        FileInputStream stream = new FileInputStream(file);
        BufferedInputStream buffer = new BufferedInputStream(stream);
        DataInputStream dataInputStream = new DataInputStream(buffer);
        System.out.println(dataInputStream.readUTF());
        System.out.println(dataInputStream.readDouble());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

标准IO

  • System.in:public final static InputStream in
    • 需要装饰InputStream->InputStreamReader->BufferedReader
  • System.out:public final static PrintStream out
    • PrintStream是OutputStream。而PrintWriter可以接受OutputStream。所以可以PrintStream->PrintWriter
  • System.err:public final static PrintStream err
  • 标准IO的重定向
    • System.setIn(文件输入如BufferedInputStream到标准输入)
    • System.setOut(标准输出定向到文件如PrintStream)
    • System.setErr(标准输出定向到文件如PrintStream)

进程控制

Process process = new ProcessBuilder(command_str.split(" ")).start();
process.getInputStream()得到一个process标准输出的InputStream

新IO

java.nio.*包引入新的io库,并重新实现了java.io.*
待续

对象序列化

Java对对象的序列化和反序列化
待续

压缩

  • FilterInputStream:InputStream的子类,装饰器的接口
    • CheckedInputStream:为InputStream计算CheckSum
    • InflaterInputStream:压缩类的基类
      • ZipInputStream:Zip压缩
      • GZIPInputStream:GZIP压缩
  • FilterOutputStream:装饰器
    • CheckedOutputStream:为OutputStream计算CheckSum
    • DeflaterOutputStream:解压缩的基类
      • ZipOutputStream:解压缩Zip
      • GZIPOutputStream:解压缩GZIP

GZIP

//字节流 输入
File file = new File("example.gz");
FileInputStream stream = new FileInputStream(file);
GZIPInputStream gzip = new GZIPInputStream(stream);
InputStreamReader adapter = new InputStreamReader(gzip);
BufferedReader reader = new BufferedReader(adapter);
String tmp = reader.readLine();
//字符流 输出
File file = new File("example.gz");
FileOutputStream stream = new FileOutputStream(file);
GZIPOutputStream gzip = new GZIPOutputStream(stream);
BufferedOutputStream writer = new BufferedOutputStream(adapter);
writer.write("this is a test");

ZIP

Java的Zip库更全面

//压缩
File file = new File("example.zip");
FileOutputStream stream = new FileOutputStream(file);
CheckedOutputStream checksum = new CheckedOutputStream(stream, new Adler32());//加入校验码Adler32(),或者CRC32()等
ZipOutputStream zip = new ZipOutputStream(checksum);//Zip输出流
BufferedOutputStream buffer = new BufferedOutputStream(zip);
zip.setComment("a test");//加入评论等
ArrayList<String> filenames = new ArrayList<>();
filenames.add("example.txt");
//Zip文件中的子文件或者目录filename为"data.txt"或者"/directory"
for (String filename : filenames) {
    zip.putNextEntry(new ZipEntry(filename));
    //此时文件的buffer里指针在新的ZipEntry的起始位置,可以写入
    int byteData = -1;
    buffer.write(byteData);
    buffer.flush();
}
buffer.close();
//解压缩
File file = new File("example.zip");
FileInputStream stream = new FileInputStream(file);
CheckedInputStream checksum = new CheckedInputStream(stream, new Adler32());
ZipInputStream zip = new ZipInputStream(checksum);
BufferedInputStream buffer = new BufferedInputStream(zip);
ZipEntry zipEntry;
while(zipEntry = = zip.getNextEntry() != null){
//getNextEntry()会使得指针调到下一个ZipEntry的起始位置
    int byteData;
    while(byteData = buffer.read() != null) System.out.write(x);
}
System.out.print(checksum.getChecksum().getValue());
buffer.close();
  • 对于读Zip的操作,可以用ZipFile对象读文件,再用entries()方法来向ZipEntries返回枚举
  • Zip格式也被用于Java档案文件JAR(Java ARchive)

XML

XML是一种更为通用的方法。java本身有java.xml.*类库。书中采用XOM库。
本质是XML文件的解析和编写过程,对应为程序的读写。
root - child结构

<?xml version="1.0" encoding="ISO-8859-1"?>
<people>
    <person>
        <first>Dr. Bunsen</first>
        <last>Honeydew</last>
    </person>
    <person>
        <first>Gonzo</first>
        <last>Res</last>
    </person>
</people>

Preferences

Preferences API是一个键值对集合,通常用于创建以类名命名的单一节点。
如:

public class PreferencesDemo{
    public static void main(String[] args){
        Preferences prefs = Preferences.userNodeForPackage(PreferencesDemo.class);//用户
        //PreferencesDemo.class在此处作为标识节点
        //Preferences.systemNodeForPackage()最好用于通用配置
        prefs.put("Location","shenzhen");
        prefs.putInt("Companions",4);
        for(String key:prefs.keys()){
            print(key+":"+prefs.get(key,null));//put default value
        }
    }
}


/*output:
Location:shenzhen
Companions:4
*/

相关文章

  • Thinking in Java - Java-IO系统笔记

    title: Java-IO系统笔记date: 2017-04-03 11:14:30categories: Ja...

  • JAVA-IO(二)

    JAVA-IO(二) sschrodinger 2019/05/21 引用 Java se 1.8 api JAV...

  • JAVA-IO(三)

    JAVA-IO(三) sschrodinger 2019/05/22 引用 长着胡萝卜须的栗子博客 Java ni...

  • Thinking in Java 笔记

    Java 与其他语言的不同之处,是它在设计的时候就把目标专注于克服开发与维护程序的复杂性。然而很多EE特性和乱七八...

  • 『读书笔记』—— Thinking_In_Java_13_字符串

    Thinking in java 读书笔记系列 不可变 String String 对象是不可变的,具有只读特性。...

  • JAVA-IO(一)

    JAVA-IO(一) sschrodinger 2019/05/21 引用 聊聊同步、异步、阻塞与非阻塞 - 猿码...

  • 『读书笔记』—— Thinking_In_Java_14_类型信

    Thinking in java 读书笔记系列 运行时类型信息使得你可以在程序运行时发现和使用类型信息。Java ...

  • Thinking in Java 笔记碎片

    复用类 P135 垃圾收集器可能永远也无法被调用,即使被调用,它也可能以任何他想要的顺序来回收对象。因此最好除了内...

  • Thinking in Java--初始化

    Thinking in Java(2)---初始化 ok,今天我看到在Thinking in java中的内容和大...

  • java-IO

    1、什么是IO流? 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为...

网友评论

      本文标题:Thinking in Java - Java-IO系统笔记

      本文链接:https://www.haomeiwen.com/subject/qkhrpftx.html