Java-字节流、字符流

  1. 字节操作流:OutputStream、inputStream
  2. 字符操作流:Writer、Reader

字节流

操作流程:(如果要操作文件)

  1. 首先通过File类对象找到一个要操作的文件路径(如果不存在则创建路径)
  2. 通过字节流或字符流的子类为字节流或字符流的对象实例化(向上转型)
  3. 执行读写操作
  4. 关闭资源

一、字节输出流OutputStream

由于OutputStream类是一个抽象类,因此需要定义其子类。对于文件操作,则使用FileOutputStream子类完成,其构造方法有两种:

  1. 实例化FileOutputStream:public FileOutputStream(File file) throws FileNotFoundException
  2. 实例化FileOutputStream(追加):public FileOutputStream(File file, boolean append) throws FileNotFoundException

取得OutputStream类的实例化对象后,使用以下三个方法进行输出操作。

  1. 输出单个字节数据:public abstract void write(int b) throws IOException
  2. 输出一组字节数据:public void write(byte[] b) throws IOException
  3. 输出部分字节数据:public void write(byte[] b, int off, int len) throws IOException
package com.joeaaa.file;

import java.io.*;

/*
* 字节流输出 OutputStream
*/
public class OutputStreamTest {
    public static void main(String[] args) throws IOException {
        File file1 = new File("/Users/joe/IdeaProjects/java/demo1/src/com/joeaaa/1.txt");// 定义文件路径
        if(!file1.getParentFile().exists()){ // 如果父路径不存在
            file1.getParentFile().mkdirs(); // 创建父路径
        }
        OutputStream outputStream1 = new FileOutputStream(file1); // 通过子类实例化对象
        // OutputStream outputStream1 = new FileOutputStream(file1, true); // 通过子类实例化对象,追加模式
        String data = "hello 20200401"; // 要输出的数据
        outputStream1.write(data.getBytes()); // 同构字节流数组输出
        outputStream1.close(); // 关闭资源
    }
}

二、字节数入流 InputStream

public abstract class InputStream extends Object implements Closeable
  1. 读取单个字节数据:public abstract int read() throws IOException 如果读到结尾返回-1
  2. 读取一组字节数据:public int read(byte[] b) throws IOException…
  3. 读取部分字节数据:public int read(byte[] b, int off, int len) throws IOException …
package com.joeaaa.file;

import java.io.*;

/*
 * 字节流输入 InputStream,一次性读取(开辟一个1024的数组> 文件长度)
 */
public class InputStreamReadAllTest {
    public static void main(String[] args) throws IOException {
        File file2 = new File("/Users/joe/IdeaProjects/java/demo1/src/com/joeaaa/1.txt");// 定义文件路径
        if(file2.exists()){ // 文件存在才能读取
            InputStream inputStream = new FileInputStream(file2);
            byte[] data = new byte[1024]; // 阅读框长度1024
            int len = inputStream.read(data); // 返回读取数据的长度
            inputStream.close();
            System.out.println("读取的数据为:"+ new String(data,0,len));
        }
    }
}
package com.joeaaa.file;

import java.io.*;

/*
 * 字节流输入 InputStream,单个字节读取(当读取完毕后,int read()返回-1)
 */
public class InputStreamOneByOneTest {
    public static void main(String[] args) throws IOException {
        File file3 = new File("/Users/joe/IdeaProjects/java/demo1/src/com/joeaaa/1.txt");// 定义文件路径
        if(file3.exists()){ // 文件存在才能读取
            InputStream inputStream3 = new FileInputStream(file3);
            byte[] data = new byte[1024]; // 阅读框长度1024

            int foot = 0;
            int temp = 0;
            while (((temp = inputStream3.read()) != -1)){
                data[foot++] = (byte)temp;
            }
            inputStream3.close();
            System.out.println("读取的数据为:"+ new String(data,0,foot));
        }
    }
}

字符流

Writer类中定义的write()方法是以字符数据为主,直接输出一个字符串使用:

public void write(String str) throws IOException
Writer out = new FileWriter(file);
String data = "xxxxx";
out.write(data);

Reader是一个抽象类,从文件读取使用FileReader类

Reader in = new FileReader(file);
char[] data  = new char[1024];
int len = in.read(data);
sout(new String(data, 0, len);
in.close()

Q:字节流与字符流的区别

  1. 字节流在IO操作时,直接针对文件;字符流是针对缓存区,然后由缓存操作文件。即:使用字节流的时候,如果不close,内容也会到文件中;但使用字符流如果不close,内容只有在手动调用flush()时,才从缓冲区输出。
  2. 处理各种数据都可以使用字节流,处理中文的时候使用字符流会更好。