Java超全面笔记(十)--- IO流

File

  1. File类的一个对象,代表一个文件或一个文件目录(文件夹)
  2. File类声明在java.io下
  3. File类中涉及到关于文件或文件目录的创建、删除、重命名、修改时间等方法,没有涉及到写入或读取文件内容的操作
  4. 后续File类的对象常会作为参数传递到流的构造器中,指明读取或写入的“终点”

  1. 创建File类的实例(3种构造器)
    File(String filePath)
    File(String parentPath,String childPath)
    File(File parentFile,String childPath)
  2. 相对路径:相对于某个路径下,指明的路径(在一个module下的java文件写的即相对于该module而言的路径)
    绝对路径:包含盘符在内的文件或文件目录的路径
  3. 路径分隔符
    windows/DOS: \\
    UNIX/URL: /

File类的常用方法

如:file1.renameTo(file2)

如果想返回true,需要file1在硬盘中存在,file2再硬盘中不存在

流的分类

  1. 操作数据单位:字节流、字符流
  2. 数据的流向:输入流、输出流
  3. 流的角色:节点流、处理流

  1. 对于文本类文件(.txt .java .c .cpp),使用字符流处理
  2. 对于非文本类文件(.jpg .mp3 .mp4 .avi .doc .ppt …),使用字节流处理

流的体系结构

抽象基类

节点流(或字符流)

缓冲流(处理流的一种)

InputStream

FileInputStream

BufferedInputStream

OutputStream

FileOutputStream

BufferedOutputStream

Reader

FileReader

BufferedReader

Writer

FileWriter

BufferedWriter

【属于字节流还是字符流看最后一个单词。Streamà字节流;Reader/Writerà字符流】

节点流/字符流:直接作用在文件上

缓冲流:作用在节点流/字符流上,或在缓冲流上

【从外部进Java环境Input/Reader,从Java环境到外部Output/Writer

File file = new File("hello.txt");

文件在当前module中:语句写在@Test下路径相对于当前module;写在main()下路径相对于当前工程

读取:

public void test1() throws IOException {
    //1.实例化File类的对象,指明要操作的文件
    File file = new File("hello.txt");
    //2.提供具体的流
    FileReader fr = new FileReader(file);
    //3.数据的读入
    int data = fr.read();
    while (data!= -1){
        System.out.println((char)data);
        data = fr.read();
    }
    //4.流的关闭
    fr.close();
}
  1. read():返回读入的一个字符。如果达到文件末尾,返回-1
  2. 为了保证流资源一定可以执行关闭操作,要使用try-catch-finally
  3. 读入的文件一定要存在,否则报异常

read(char[] cbuf):返回每次读入cbuf数组中的字符的个数。如果达到文件末尾,返回-1

while ((len = fr.read(cbuf))!=-1){
    //方式一、
    for (int i = 0; i < len; i++) {
        System.out.print(cbuf[i]);
    }
    //方式二
    String str = new String(cbuf,0,len);
    System.out.print(str);
}

写入:

public void test3(){

    FileWriter fw = null;

    try {

        File file = new File("hello.txt");



        fw = new FileWriter(file,true);



        fw.write("good good !");

    } catch (IOException e) {

        e.printStackTrace();

    } finally {

        try {

            fw.close();

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

}

输出操作,对应的File可以不存在

1)    如果不存在,在写入过程中,会自动创建此文件

2)    如果已经存在:

i)     使用构造器FileWriter(file,false)/ FileWriter(file):对原文件覆盖

ii)    使用构造器FileWriter(file,true):不会覆盖,在原文件基础上添加

缓冲流(处理流之一)

提升流的读取、写入速度:内部提供了一个缓冲区

public void test2(){
    FileInputStream fis = null;
    FileOutputStream fos = null;
    BufferedInputStream bis = null;
    BufferedOutputStream bos = null;
    try {
        File srcFile = new File("picture.jpg");
        File desFile = new File("picture2.jpg");

        fis = new FileInputStream(srcFile);
        fos = new FileOutputStream(desFile);

        bis = new BufferedInputStream(fis);
        bos = new BufferedOutputStream(fos);


        byte[] buffer = new byte[5];
        int len;
        while ((len = bis.read(buffer)) != -1){
            bos.write(buffer,0,len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (bis!=null){
            try {
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (bos!=null){
            try {
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
           
    }
}

资源关闭:先关外层缓冲流、再关内层节点流

【关闭外层流的同时,内层流也会自动进行关闭。所以内层流的关闭,可以省略】

转换流(处理流之二)

  1. 属于字符流
    InputStreamReader:将一个字节的输入流转换为字符的输入流
    OutputStreamWriter:将一个字符的输出流转换为字节的输出流
  2. 作用:提供字节流和字符流之间的转换
  3. 解码:字节、字节数组à字符数组、字符串
    编码:字符数组、字符串à字节、字节数组
  4. 字符集
InputStreamReader isr = new InputStreamReader(fis ,"UTF-8");

参数1指明输入的字节流,参数2指明字符集(可以省略,使用系统默认的字符集)。具体使用哪个字符集,取决于文件xxx.txt保存时使用的字符集

标准输入、输出流(处理流之三)

  1. System.in:标准输入流,默认从键盘输入
    System.out:标准输出流,默认从控制台输出
  2. System类的setIn(InputStream is)/setOut(PrintStream ps)方式重新制定输入和输出的流

打印流(处理流之四)

PrintStream

PrintWriter

提供了一系列重载的print()和println()

PrintStream ps = null;
FileOutputStream fos = new FileOutputStream("hello.txt");

ps = new PrintStream(fos, true);
if (ps!=null){
    System.setOut(ps);
}

for (int i = 0; i <= 255; i++) {
    System.out.println((char)i);
}

通过setOut()可以将输入流直接写进文件中,不在控制台显示

数据流(处理流之五)

DataInputStream

DataOutputStream

【数据流写入的文件正常打开显示的会有问题,需要用数据流读取再显示】

作用:用于读取或写出基本数据类型的变量或字符串

写入数据:

DataOutputStream dos = new DataOutputStream(new FileOutputStream("dos.txt"));
dos.writeUTF("孙狗");
dos.flush();//刷新,将内存中的数据写入文件
dos.writeInt(123);
dos.flush();

dos.close();

读取数据:

DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
String name = dis.readUTF();
int score = dis.readInt();

System.out.println(name+""+score);

将文件中存储的基本数据类型变量和字符串读取到内存中,保存在变量中

【读取不同类型的数据的顺序要与当初写入文件时,保存的数据的顺序一致,否则出错】

对象流(处理流之六)

  1. ObjectInputStream
    ObjectOutputStream
  2. 作用:存储和读取基本数据类型数据或对象的处理流。强大之处在于可以把Java中的对象写入到数据源中,也能把对象从数据源中还原。
  3. 序列化过程:将内存中的java对象保存到磁盘中或通过网络传输出去à ObjectOutputStream
    反序列化过程:将磁盘文件中的对象还原为内存中的一个java对象à ObjectInputStream
  4. 可序列化的要求
    1. 需要实现接口:Serializable
    2. 需要当前类提供一个全局常量(值可以自定义,不要重复)
public static final long serialVersionUID = 64645131234545L;

【如果没有显式定义serialVersionUID,java运行环境根据类的内部细节自动生成一个值。如果类的内部实例变量做了修改,serialVersionUID可能会发生变化。发生变化后反序列化可能会出错】

    1. 除了当前类需要实现Serializable接口外,必须保证其内部所有属性都是也必须是可序列化的。(默认情况下,基本数据类型可以序列化)
  1. ObjectInputStream和ObjectOutputStream不能序列化static和transient修饰的成员变量

随机存取文件流(处理流之七)

RandomAccessFile类

  1. 直接继承于java.lang.Object类,实现了DataInput和DataOutput
  2. 既可以作为一个输入流,又可以作为一个输出流
RandomAccessFile raf1 = new RandomAccessFile(File file, String mode);

        mode:”r”  只读;”rw” 可读可写;【没有”w”】

        3. 如果作为一个输出流时,写出到的文件如果不存在,则在执行过程中自动创建;
            如果写出到的文件存在,会对原文件从头开始覆盖

        4. seek(long pos):从下标为pos的位置开始覆盖

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值