字符流和字节流的区别

字节流

字节流是指传输过程中,传输数据的最基本单位是字节的流,一个不包含边界数据的连续流;字节流是由字节组成的,主要用在处理二进制数据。
字节流结果

OutputStream字节输出流

常用方法

这个抽象类是所有表示字节输出流的类的超类。具体方法如下:

  1. write(int b)
    将指定的字节写入此输出流
  2. write(byte b[])
    将指定字节数组中的b.length个字节写入此输出流
  3. write(byte b[], int off, int len)
    将指定字节数组中的len个字节从偏移量off开始写入此输出流。 write(b, off, len)的一般约定是将数组b中的某些字节按顺序写入输出流; 元素b[off]是写入的第一个字节, b[off+len-1]是此操作写入的最后一个字节
  4. flush()
    刷新此输出流并强制写出任何缓冲的输出字节
  5. close()
    关闭此输出流并释放与此流关联的任何系统资源

FileOutputStream

FileOutputStream继承OutputStream,有两个常用构造方法

  1. FileOutputStream(File file)
    对文件file进行覆盖写入

  2. FileOutputStream(File file, boolean append)
    append:true 代表追加写入

    写入举例

  3. 覆盖写入

      public static void write() throws IOException {
        File f = new File("d:" + File.separator + "test.txt");
        //如果文件不存在会自动创建
        OutputStream out = new FileOutputStream(f);
        String str = "Hello World\nsddgdgdf";
        //因为是字节流,所以要转化成字节数组进行输出
        byte[] b = str.getBytes();
        out.write(b);
        out.close();
    }
  4. 追加写入

     public static void continueWrite() throws IOException {
        File f = new File("d:" + File.separator + "test.txt");
        //如果文件不存在会自动创建
        OutputStream out = new FileOutputStream(f,true);
        String str = "Hello World\nsddgdgdf3434";
        //因为是字节流,所以要转化成字节数组进行输出
        byte[] bytes = str.getBytes();
        for (byte b: bytes){
            out.write(b);
        }
        out.close();
    }

    InputStream字节输入流

    这个抽象类是表示字节输入流的所有类的超类

    常用方法

  5. read()
    从输入流中读取下一个字节的数据。 值字节以0到255范围内的int形式返回。 如果由于已到达流末尾而没有可用字节,则返回值-1 。 此方法会阻塞,直到输入数据可用、检测到流结束或抛出异常为止

  6. read(byte b[])
    从输入流中读取一定数量的字节并将它们存储到缓冲区数组b 。 实际读取的字节数作为整数返回。 此方法会阻塞,直到输入数据可用、检测到文件结尾或抛出异常。
    如果b的长度为零,则不读取字节并返回0 ; 否则,将尝试读取至少一个字节。 如果由于流位于文件末尾而没有可用字节,则返回值-1 ; 否则,至少读取一个字节并将其存储到b 。
    读取的第一个字节存储到元素b[0] ,下一个存储到b[1] ,依此类推。 读取的字节数最多等于b的长度。 令k为实际读取的字节数; 这些字节将存储在元素b[0]到b[ k -1] ,而元素b[ k ]到b[b.length-1]不受影响。

  7. read(byte b[], int off, int len)
    从输入流中读取最多len个字节的数据到一个字节数组中。 尝试读取多达len个字节,但可能会读取较小的数字。 实际读取的字节数作为整数返回。
    读取的第一个字节存储到元素b[off] ,下一个存储到b[off+1] ,依此类推

  8. skip(long n)
    跳过并丢弃此输入流中的n字节数据,在跳过n个字节之前到达文件末尾, 返回实际跳过的字节数并抛出异常。 如果n为负,则InputStream类的skip方法始终返回 0

  9. available()
    返回当前可以跳过的最大值

  10. close()

  11. markSupported()
    如果此流实例支持标记和重置方法,则为true ; 否则为false

  12. mark(int readlimit)
    标记此输入流中的当前位置。 对reset方法的后续调用将此流重新定位在最后标记的位置,以便后续读取重新读取相同的字节。

  13. reset()
    将此流重新定位到上次在此输入流上调用mark方法时的位置

读取举例

  1. 文件大小确定
```java
public static void read() throws IOException {
        File f = new File("d:" + File.separator + "test.txt");
        InputStream inputStream = new FileInputStream(f);
        //可以根据文件的大小设置字节数组的长度
        long length = f.length();
        byte[] bytes = new byte[(int) length];
        int len = inputStream.read(bytes);
        inputStream.close();
        String s = new String(bytes, 0, len);
        System.out.println(s);

    }
```
  1. 文件大小不确定

    public static void readNoSize2() throws IOException {
        File f = new File("d:" + File.separator + "test.txt");
        InputStream inputStream = new FileInputStream(f);
        StringBuilder builder = new StringBuilder();
        byte[] bytes = new byte[6];
        int temp = 0, len = 0;
        //-1文件读取完毕
        while ((temp = inputStream.read()) != -1) {
            bytes[len] = (byte) temp;
            len++;
            if (len == 6) {
                builder.append(new String(bytes));
                len = 0;
            }
        }
        builder.append(new String(bytes, 0, len));
        inputStream.close();
        System.out.println(builder);
    
    }

字符流

字节流就是普通的二进制流,读出来的是bit,而字节流不便于处理Unicode形式存储的信息。字符流就是在字节流的基础按照字符编码处理,处理的是char。
字符流结构

Reader

常用方法

  1. read()

  2. read(char cbuf[])

  3. read(char cbuf[], int off, int len)

  4. skip(long n)

  5. ready():告诉这个流是否准备好被读取

  6. markSupported()

  7. mark(int readAheadLimit)

  8. reset()

  9. close()

    字符流读取举例

    1. 文件大小确定
       public static void read() throws IOException {
           File f = new File("d:" + File.separator + "test.txt");
           Reader out = new FileReader(f);
           char[] chars = new char[(int) f.length()];
           int len = out.read(chars);
           out.close();
           System.out.println(new String(chars, 0, len));
       }
    
    1. 文件大小不确定
```java
public static void readNoSize() throws IOException {
    File f = new File("d:" + File.separator + "test.txt");
    Reader out = new FileReader(f);
    char[] arrs = new char[6];
    StringBuilder builder = new StringBuilder();
    int len = 0;
    int temp = 0;
    while ((temp = out.read()) != -1) {
        arrs[len] = (char) temp;
        len++;
        if (len == 6) {
            builder.append(arrs);
            len = 0;
        }
    }
    builder.append(arrs, 0, len);
    out.close();
    System.out.println(builder);
}
```

Writer

用于写入字符流的抽象类;内置一个保存字符串和单个字符写入的临时缓冲,大小为1024

常用方法

  1. write(char cbuf[])
  2. write(char cbuf[], int off, int len)
  3. write(String str) :写入一个字符串
  4. write(String str, int off, int len)
  5. append(CharSequence csq):将指定的字符序列附加到此编写器
  6. append(CharSequence csq, int start, int end)
  7. append(char c)
  8. flush()
    冲洗流。 如果流已将来自各种 write() 方法的任何字符保存在缓冲区中,则立即将它们写入其预期目的地。 然后,如果该目标是另一个字符或字节流,则刷新它。 因此,一次 flush() 调用将刷新 Writers 和 OutputStreams 链中的所有缓冲区
  9. close()

    字符流写入举例

public static void writer() throws IOException {
        File f = new File("d:" + File.separator + "test.txt");
        //覆盖原有的
        Writer out = new FileWriter(f);
        String str = "Hello World";
        out.write(str);
        out.close();
    }

字符流和字节流区别

  1. 字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串;
  2. 字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以
  3. 字节流默认不使用缓冲区;字符流使用缓冲区
  4. 在硬盘上的所有文件都是以字节形式存在的(图片,声音,视频),而字符值在内存中才会形成。

   转载规则


《字符流和字节流的区别》 duan 采用 知识共享署名 4.0 国际许可协议 进行许可。
  目录