File类和IO流

第一章:IO流

第二章:字节流

2.1 字节输出流【OutputStream】

java.io.OutputStream抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地。它定义了字节输出流的基本共性方法。

所有方法:

  • public void close():关闭此输出流并释放与此流相关联的任何系统资源;
  • public void flush():刷新此输出流并强制写出所有缓冲的输出字节;
  • public void write(byte[] b):将b.length字节从指定的字节数组写入此输出流;
  • public void write(byte[] b, int off, int len):从指定的字节数组中从偏移量off开始的len字节写入此输出流;
  • public abstract void write(int b):将指定的字节写入此输出流;

小贴士:

close方法,当完成流的操作时,必须调用此方法,释放系统资源。

2.2 FileOutputStream类

java.io.FileOutputStream extends OutputStream:文件字节输出流,作用是把内存中的数据写入到硬盘的文件中。

常用构造方法:

  • FileOutputStream(String path):创建一个向具有指定名称的文件中写入数据的输出文件流;

  • FileOutputStream(File file):创建一个向指定File对象表示的文件中写入数据的文件输出流;

    参数:写入数据的目的地

    ​ String name:目的地是一个文件的路径

    ​ File file:目的地是一个文件

    构造方法的作用:

    ​ 1、先创建一个FileOutputStream对象;

    ​ 2、会根据构造方法中传递的文件路径/文件创建一个空的文件;

    ​ 3、会把FileOutputStream对象指向创建好的文件;

写入数据的原理:

​ Java程序 --> JVM(Java虚拟机)--> OS(操作系统)--> OS调用写数据的方法 --> 把数据写入到文件中

写换行:

直接写换行符号即可,例如 => Windows:\r\n,Linux:/n,Mac:/r;

public class 字节流 {
    public static void main(String[] args) throws IOException {
        File f = new File("a.txt");
        FileOutputStream fos = new FileOutputStream(f,true);
        /* 在Windows中,数据带上\r\n即表示换行的意思 */
        fos.write("\r\n你好".getBytes());
        fos.close();
    }
}

数据追加续写:

每次创建输出流对象时,对文件写入都会覆盖原文件的内容,要使得数据每次都是以追加的形式,只需要在FileOutputStream的构造方法的参数中,再加入一个boolean参数,例如:

  • public FileOutputStream(File file, boolean append)
  • public FileOutputStream(String name, booloean append)

其中true表示追加数据,false表示清空原有数据,默认为false

package file_io;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class 字节流 {
    public static void main(String[] args) throws IOException {
        File f = new File("D:\\Web学习资料\\first\\1-3-Java语言高级\\06-File类与IO流\\04 IO字节流\\a.txt");
        /* FileOutputStream的构造方法中第二个参数即为追加开关,true表示追加,false表示覆盖 */
        FileOutputStream fos = new FileOutputStream(f,true);
        fos.write("你好,这是我写的一个数据".getBytes());
        fos.close();
    }
}

2.3 字节输入流【InputStream】

java.io.InputStream抽象类是表示字节输入流的所有类的超类。它定义了字节输入流的基本共性方法。

常用方法:

  • int read():从输入流读取数据的下一个字节;

  • int read(byte[] b):从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中;

  • int read(byte[] b, int off, int len)

    如果读取了有效的字节,则返回读取的有效字节数,反之则返回-1

  • void close():关闭此输入流并释放与该流关联的所有系统资源;

2.4 FileInputStream类

java.io.FileInputStream extends InputStream:文件字节输入流,作用是将硬盘中的数据读取到内存中。

构造方法:

  • FileInputStream(String name):通过路径打开一个实际的文件

  • FileInputStream(File file):通过File对象打开一个实际的文件

    构造方法的作用:

    ​ 1、会创建一个FileInputStream对象;

    ​ 2、会把上述对象指定构造方法中要读取的文件;

举例:

package file_io;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class 读取文件 {
    public static void main(String[] args) throws IOException {
        File f = new File("D:\\Web学习资料\\first\\1-3-Java语言高级\\06-File类与IO流\\04 IO字节流\\a.txt");
        FileInputStream inputStream = new FileInputStream(f);
        byte[] b = new byte[100];
        int read = inputStream.read(b);
        System.out.println(new String(b,0,read));
        System.out.println(read);
        inputStream.close();
    }
}

2.5 拷贝文件示例

这里经过本人测试,发现提示复制成功的一个.avi视频文件打不开,一开始打算将从输入流读取的字节数组转化成了字符串,再将字符串转化成字节数组,放至输出流中,这样的话是有问题的,通过查阅资料,也了解到了字节流和字符流操作的区别具体如下:

  • 字符流主要针对一些文本文档(比字节流操作的效率要高),比如.txt、.doc,而pdf就不行。
  • 字节流几乎可以对任何文件类型进行操作,主要是对非文件类型的,如媒体文件(音频,视频,图片…)。

注意事项:

当使用字节流读取文本文件时,可能会存在一个问题,就是遇到中文字符时,可能不会显示完整的字符,那是因为一个中文字符可能占用多个字节存储。所以Java提供一些字符流类,以字符为单位读写数据,专门用来处理文本文件。

package file_io;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class 拷贝任意文件 {
    public static void main(String[] args) throws IOException {
        // 给拷贝文件计时
        long begin = System.currentTimeMillis();
        // 创建一个读的字节流
        FileInputStream inputStream = new FileInputStream("D:\\Web学习资料\\first\\1-3-Java语言高级\\06-File类与IO流\\04 IO字节流\\1_8_4_01_IO概述(概念&分类).avi");
        // 创建一个写的字节流
        FileOutputStream outputStream = new FileOutputStream("D:\\Web学习资料\\first\\1-3-Java语言高级\\06-File类与IO流\\04 IO字节流\\newFile.avi",true);
        // 创建一个字节数组缓冲区,长度定为1024字节
        byte[] b = new byte[1024];
        // 定义len表示有效字节长度
        int len = 0;
        // 开始循环读取文件
        while ((len = inputStream.read(b)) != -1) {
            // 方法一:错误
            // 先将有效的部分转化成字符串,然后再转化为字符数组
            // 这种思路是有问题的,为什么呢?
            // 因为视频格式读取的字节流若是转化成字符串,则会存在错误,导致拷贝的新文件打不开
            // outputStream.write(new String(b,0,len).getBytes());
            // 方法二:正确
            // 将每次从输入流读取的字节数组中有效的部分取出来,然后写入输出流
            outputStream.write(b,0,len);
        }
        // 关闭输出流
        outputStream.close();
        // 关闭输入流
        inputStream.close();
        // 计时结束
        long end = System.currentTimeMillis();
        System.out.println("本次拷贝文件共耗时:" + (end - begin) + "ms");
    }
}

第三章:字符流

3.1 字符输入流【Reader】

java.io.Reader抽象类是表示用于读取字符流的所有类的超类,可以读取字符信息到内存中。它定义了字符输入流的基本共性功能方法。

  • public void close():关闭此流并释放与此流相关联的任何系统资源;
  • public int read():从输入流读取一个字符,并将此字符转成int型数据;
  • public int read(char[] cbuf):从输入流读取一些字符,并将他们存储到字符数组cbuf中,返回值为读取的有效长度;

3.2 FileReader类

java.io.FileReader类是读取字符文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。

小贴士:

1.字符编码:字节与字符的对应规则。Window系统的中文编码默认是GBK编码表。

构造方法:

  • FileReader(File file):

  • FileReader(String filename):

    参数:String filename => 文件路径;File file => 文件对象;

    作用:1、创建一个FileReader对象,并把该对象指向要读取的文件;

使用步骤:

  1. 创建FileReader对象,构造方法中绑定要读取的数据源;
  2. 使用FileReader对象中的方法read读取文件;
  3. 释放资源;

举例:

package file_io;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class FileReader读取单个字符 {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("D:\\个人资料\\aaa.txt");
        // 方法一:
        int len = 0;
        // read方法读取出来的是字符的int类型字符数据,
        // 如果需要还原成真实的数据,只需要强转一下即可
        // 未读取到字符则返回-1
        while((len = fr.read()) != -1) {
            System.out.print((char)len);;
        }
        // 方法二:
        int yxlen = 0;
        char[] ch = new char[1024];
        while((yxlen = fr.read(ch)) != -1) {
            // 使用String类的构造方法,输出字符数组的内容
            System.out.print(new String(ch,0,yxlen));
        }
    }
}

3.3 字符输出流【Writer】

java.io.Writer抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地。它定义了字符输出流的基本共性功能方法。

  • void write(int c):写入单个字符
  • void write(char[] cbuf):写入字符数组
  • abstract void write(char[] cbuf, int off, int len):写入字符数组的某一部分,从off索引开始,len个长度的字符
  • void write(String str):写入字符串
  • void write(String str, int off, int len):写入字符串的某一部分,从off索引开始,len个字符的长度
  • void flush():刷新该流的缓冲
  • void close():关闭该输出流,但是先刷新它

3.4 FileWriter类

java.io.FileWriter类是写出字符到文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。

构造方法:

  • FileWriter(File file):根据给定的File对象构造一个FileWriter对象
  • FileWriter(File file, boolean append):在上述中,增加可追加的设置
  • FileWriter(String fileName):根据给定的文件路径构造一个FileWriter对象
  • FileWriter(String fileName, boolean append):在上述中,增加可追加的设置

使用步骤:

  1. 创建FileWriter对象,构造方法中绑定要写入数据的目的地;

  2. 使用FileWriter中的方法write,把数据写入到内存缓冲区中(此时内部有字符转化为字节的过程);

  3. 使用FileWriter中的方法flush,把内存缓冲区中的数据,刷新到文件中;

  4. 释放资源(会先把内存缓冲区中的数据刷新到文件中)

    如果不使用 flush或者 close,则数据随代码的执行,在内存缓冲区中停留一段时间后会自动消失,不会被写入文件中!

flush和close方法的区别:

  • flush:刷新缓冲区,流对象可以继续使用;
  • close:先刷新缓冲区,然后通知系统释放资源,流对象不可以再被使用了;

换行符号:

  1. Windows: \r\n
  2. Linux: /n
  3. Mac: /r

举例一(FileWriter的常规使用):

package file_io;

import java.io.FileWriter;
import java.io.IOException;

public class FileWriter写入数据 {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("D:\\个人资料\\bbb.txt", true);
        // 先写到内存缓冲区中,
        // 如果后续没有使用flush或close,则内存缓冲区中的数据压根不会存到文件中去
        fw.write("123456789",0,3);
        fw.write(new char[]{'中', '国', '加', '油'},0,2);
        // 将内存缓冲区中的数据刷新到文件中
        fw.flush();
        // 会先刷新一次
        fw.close();
    }
}

举例二(写入的数据进行换行操作):

package file_io;

import java.io.FileWriter;
import java.io.IOException;

public class 使用FileWriter写入换行 {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("D:\\个人资料\\bbb.txt", true);
        for (int i = 0; i < 10; i++) {
            fw.write(97 + i);
            // 写入换行符号
            fw.write("\r\n");
        }
        fw.close();
    }
}

第四章:IO的异常处理

猜你喜欢

转载自www.cnblogs.com/carle/p/12095380.html