栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java有关文件(File)和IO流的学习笔记

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java有关文件(File)和IO流的学习笔记

IO流概念

IO流即Input流和Output流

流(Stream)可以理解为内存与磁盘建立的一条传输数据的通道,Input流是从内存向磁盘传输数据的通道(写文件),Output流是从磁盘向内存传输数据的通道(读文件)

分类

字节流、字符流

区别在于字节流和字符流所操作的数据单元不同,字节流操作的单元是数据单元是8位的字节,字符流操作的是数据单元为16位的字符。

字节流可以处理一切文件,而字符流只能处理纯文本文件。

File类

表示磁盘中的文件或者目录(文件夹)

构造方法

 常用方法  获取功能的方法

        public String getAbsolutePath() :返回此File的绝对路径名字符串。
        public String getPath() :将此File转换为路径名字符串。
        public String getName() :返回由此File表示的文件或目录的名称。
        public long length() :返回由此File表示的文件的⻓度。

判断功能的方法

        public boolean exists() :此File表示的文件或目录是否实际存在。
        public boolean isDirectory() :此File表示的是否为目录。
        public boolean isFile() :此File表示的是否为文件。

创建删除功能的方法

        public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
        public boolean delete() :删除由此File表示的文件或目录。
        public boolean mkdir() :创建由此File表示的目录。
        public boolean mkdirs() :创建由此File表示的目录,包括任何必需但不存在的父目录。

方法实操以及注释
package b_file;

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

public class Demo1 {
    public static void main(String[] args) throws IOException {
        // 使用路径创建 File 对象
        File file = new File("dd/ff/ee/gg");
        System.out.println(file);

        // 判断文件或者目录是否存在
        boolean exists = file.exists();
        System.out.println("是否存在: " + exists);

        // 判断是否是文件
        boolean file1 = file.isFile();
        System.out.println("是否是文件: " + file1);

        // 判断是否是目录
        boolean directory = file.isDirectory();
        System.out.println("是否是目录: " + directory);

        // 创建空文件 -> 当exists是false
        boolean newFile = file.createNewFile();
        System.out.println("是否创建: " + newFile);

        // 创建空目录 -> exists-false, 父路径的目录都存在
        boolean mkdir = file.mkdir();

        // 创建目录, 顺便把不存在的父目录一起创建
        file.mkdirs();
    }
}
注意

delete()方法只能删除空文件夹和文件,如果文件夹中有文件,则不能用delete()方法直接删除,需要把文件夹中的文件删光才能用此方法删除文件夹

实现代码如下:

package b_file;

import java.io.File;

public class Demo6 {
    // 递归删除 aa 文件夹
    public static void main(String[] args) {
        File file = new File("aa");
        deleteDir(file);
    }

    public static void deleteDir(File dir) {
        // 1.列出dir目录中全部的文件对象
        File[] files = dir.listFiles();
        if (files != null && files.length != 0) {
            // 2.循环删除每一个文件对象
            for (File f : files) {
                if (f.isDirectory()) {
                    deleteDir(f); // 递归
                } else {
                    f.delete();
                }
            }
        }
        // 3.dir是空目录了, 可以直接删除
        dir.delete();
    }
}
IO流

 

字节流

一切文件数据(文本、图片、视频等)在存储时,都是以二进制数字的形式保存,都一个一个的字节,那么传输时一样如此。所以,字节流可以传输任意文件数据。在操作流的时候,我们要时刻明确,无论使用什么样的流对象,底层传输的始终为二进制数据。

InputStream与OutputStream是两个抽象类,是字节流的基类,所有具体的字节流实现类都是分别继承了这两个类。

InputStream所包含的方法

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

OutputStream所包含的方法

public void close() :关闭此输入流并释放与此流相关联的任何系统资源。
public abstract int read() :从输入流读取数据的下一个字节。
public int read(byte[] b) :从输入流中读取一些字节数,并将它们存储到字节数组 b中 。

FileOutputStream类

该类是文件输出流,用于将数据写出到文件。

构造方法

public FileOutputStream(File file) :创建文件输出流以写入由指定的 File对象表示的文件。
public FileOutputStream(String name) :创建文件输出流以指定的名称写入文件。

write方法

write(int b) 方法,写出字节,每次可以写出一个字节数据

write(byte[] b) ,写出字节数组,每次可以写出数组中的数据

write(byte[] b, int off, int len) ,写出指定⻓度字节数组,每次写出从off索引开始,len个字节

经过以上每次程序运行,创建输出流对象,都会清空目标文件中的数据。如保留目标文件中数
据,要用到以下方法


public FileOutputStream(File file, boolean append) : 创建文件输出流以写入由指定的
File对象表示的文件。
public FileOutputStream(String name, boolean append) :创建文件输出流以指定的名称
写入文件。
这两个构造方法,参数中都需要传入一个boolean类型的值, true 表示追加数据, false 表示清空原有数据。这样创建的输出流对象,就可以指定是否追加续写了

案例

package c_io;

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

// OutputStream - 抽象类
public class Demo1 {
    public static void main(String[] args) throws IOException {

         File file = new File("dd/out.txt");
        // 打开流, 打开本地磁盘文件
        FileOutputStream fos = new FileOutputStream(file);

        // append-true, 打开文件, 并写入文件末尾 (追加)
        FileOutputStream fos = new FileOutputStream(file, true);

        // 写入1个字节  0000 0000 0000 0000 0110 0000 0100 0000
        // fos.write(200);
        fos.write(-25);
        fos.write(-113);
        fos.write(-83);

        // 字节数组
        byte[] bs = {-25, -113, -83};
        // 将指定字节数组的所有字节一起写入文件中
        fos.write(bs);
        // -25, -113, -83
        // fos.flush(); 没有用


        byte[] bs1 = "天气太热了".getBytes();
        // 将bs1字节中, 从off开始, 写len个字节
        fos.write(bs1, 3, 9);

        fos.close(); // 及时释放资源 - finally

    }
}
InputStream类

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


public void close() :关闭此输入流并释放与此流相关联的任何系统资源。
public abstract int read() :从输入流读取数据的下一个字节。
public int read(byte[] b) :从输入流中读取一些字节数,并将它们存储到字节数组 b中 。

FileInputStream类

构造方法


FileInputStream(File file) :通过打开与实际文件的连接来创建一个 FileInputStream ,该文件
由文件系统中的 File对象 file命名。
FileInputStream(String name) :通过打开与实际文件的连接来创建一个 FileInputStream ,该文
件由文件系统中的路径名 name命名。

当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有该文件,会抛FileNotFoundException 。

读取字节数据方法

read ()方法:每次可以读取一个字节的数据,提升为int类型,读取到文件末尾,返回 -1

read(byte[] b) ,每次读取b的⻓度个字节到数组中,返回读取到的有效字节个数,读取到末尾时,返回 -1

案例

package a_io;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;

public class Demo2 {
    // 字符输入流
    public static void main(String[] args) throws IOException {
        FileReader reader = new FileReader("out1.txt");

        int i = reader.read();

        System.out.println("i: " + i); // 20013
        System.out.println((char)i);

        char[] chs = new char[10];
        // 最多读10个字符, 存入到 chs 数组中, 最终读出来len个字符
        int len = reader.read(chs);

        System.out.println("读出来的内容是: " + chs); // 这样是打印地址
         

        String str = new String(chs, 0, len);// 这样是打印字符序列, 即字符串
    }
}

练习 文件复制

public class Copy {
    public static void main(String[] args) throws IOException {
        // 1.创建流对象
        // 1.1 指定数据源
        FileInputStream fis = new FileInputStream("D:\test.jpg");
            // 1.2 指定目的地
            FileOutputStream fos = new FileOutputStream("test_copy.jpg");
            // 2.读写数据
            // 2.1 定义数组
            byte[] b = new byte[1024];
            // 2.2 定义⻓度
            int len;
            // 2.3 循环读取
            while ((len = fis.read(b)) != -1) {
                // 2.4 写出数据
                fos.write(b, 0, len);
            }
            // 3.关闭资源
            fos.close();
            fis.close();
    }
}
 字符流

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

字符输入流【Reader】

ava.io.Reader 抽象类是表示用于读取字符流的所有类的超类,可以读取字符信息到内存中。它定义了字符输入流的基本共性功能方法。
public void close() :关闭此流并释放与此流相关联的任何系统资源。
public int read() :从输入流读取一个字符。
public int read(char[] cbuf) :从输入流中读取一些字符,并将它们存储到字符数组 cbuf 中

FileReader类

构造方法


FileReader(File file) :创建一个新的 FileReader ,给定要读取的File对象。
FileReader(String fileName) :创建一个新的 FileReader ,给定要读取的文件的名称。
当你创建一个流对象时,必须传入一个文件路径。类似于FileInputStream。

读取字符数据

read 方法,每次可以读取一个字符的数据,提升为int类型,读取到文件末尾,返回 -1 ,循环读取

read(char[] cbuf) ,每次读取b的⻓度个字符到数组中,返回读取到的有效字符个数,读取到末尾时,返回 -1

package a_io;

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

public class Demo5Read {
    public static void main(String[] args) throws IOException {
        FileReader reader = new FileReader("dd/note.txt");
        

        int len ;
        char[] chs = new char[33];
        while ((len = reader.read(chs)) != -1) {
            String str = new String(chs, 0, len);
            System.out.print(str);
        }
        System.out.println("文件读取结束");
        reader.close();
    }
}
字符输出流【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() :关闭此流,但要先刷新它。

FileWriter类

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


构造方法:
FileWriter(File file) :创建一个新的 FileWriter,给定要读取的File对象。
FileWriter(String fileName) :创建一个新的 FileWriter,给定要读取的文件的名称。当你创建一个流对象时,必须传入一个文件路径,类似于FileOutputStream。

基本写出数据
写出字符: write(int b) 方法,每次可以写出一个字符数据

public class FWWrite {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileWriter fw = new FileWriter("fw.txt");
// 写出数据
fw.write(97); // 写出第1个字符
fw.write('b'); // 写出第2个字符
fw.write('C'); // 写出第3个字符
fw.write(30000); // 写出第4个字符,中文编码表中30000对应一个汉字。
}

write()方法参数只能填字符的编码,而且一次只能向文件中写入一个字符,局限性较大,接下来介绍更好的写入类Prinertwrite

PrinterWrite类

除了一次可以输入多个字符,构造方法、用法和上面差不多,就不多赘述了,直接看代码

package b_buffer;

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

public class Demo6PrintWriter {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("dd/out.txt", true);
        // autoFlush -> true, 只有使用println方法写入的时候, 才会自动刷新缓冲区
        PrintWriter pw = new PrintWriter(fw, true);

        // 支持所有数据类型
        pw.print(true);
        pw.println(new int[10]); // 自动刷新缓冲区

        pw.print(false); // 不会刷新缓冲区

        // 出现了异常
        int i = 1/0;

        pw.flush(); // 手动刷新缓冲区

        pw.close();
    }
}
package b_buffer;

import java.io.*;

public class Demo7PrintWriter {
    // PrintWriter 8个构造方法
    public static void main(String[] args) throws IOException {
        // 1.1直接传递一个文件名: 使用默认字符集, 清空原文件, 不会自动刷新缓冲区
        PrintWriter pw1 = new PrintWriter("out.txt");
        // 1.2传递一个文件名 + 字符集: 使用指定字符集, 清空原文件, 不会自动刷新缓冲区
        PrintWriter pw2 = new PrintWriter("out.txt", "GBK");
        // 2传递一个文件对象(或者 + 字符集): 效果同 1
        // 3.1传递一个字节流: 使用默认字符集, 清空原文件, 不会自动刷新
        FileOutputStream fos3 = new FileOutputStream("out.txt");
        PrintWriter pw3 = new PrintWriter(fos3);
        // 3.2传递一个字节流+自动刷新: 使用默认字符集, 清空原文件, 会自动刷新(println)
        FileOutputStream fos4 = new FileOutputStream("out.txt");
        PrintWriter pw4 = new PrintWriter(fos4, true);
        // 3.3传递一个字节流: 使用默认字符集, 在原文件上追加
        FileOutputStream fos5 = new FileOutputStream("out.txt", true);
        PrintWriter pw5 = new PrintWriter(fos5, true);

        // 4.传递一个字符流(或者 + 自动刷新): 效果同3
        // 5.转换流(字符流Writer)  OutputStreamWriter
        FileOutputStream fos = new FileOutputStream("out.txt", true);
        OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK");
        PrintWriter pw = new PrintWriter(osw, true);

        pw.println("你好, 今天吃了吗? 没吃呢还");

        //pw.flush();
    }
}
对象的序列化

ObjectOutputStream类和ObjectInputStream(和上面一样 都一样 人打字打麻了)

可以把内存中的对象放入磁盘中的txt里的过程叫做序列化,也可以把磁盘中序列化的对象反序列化到内存中

对象在被序列化之前,该对象的类需要实现Serializable接口才能被序列化

看代码

person类

import java.io.Serializable;

public class Person implements Serializable  {
    private String name;
    private int age;

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + ''' +
                '}';
    }
}

将对象序列化

import java.io.*;

public class IOTraining07 {
    public static void main(String[] args) throws IOException {
        Person p1=new Person(19,"张三");
        FileOutputStream fos=new FileOutputStream("aa//obj.txt");
        ObjectOutputStream oos=new ObjectOutputStream(fos);
        oos.writeObject(p1);


    }
}

将对象反序列化

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

public class IOTraining08 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        FileInputStream fis = new FileInputStream("aa//obj.txt");
        ObjectInputStream ois = new ObjectInputStream(fis);
        Person person = (Person) ois.readObject();
        System.out.println(person);
    }
}
小结:


     字节流的父类: InputStream / OutputStream
     字符流的父类: Reader / Writer

     字节流的普通子类: FileInputStream / FileOutputStream
     字符流的普通子类: FileReader / FileWriter

     带缓冲区的字节流: BufferedInputStream / BufferedOutputStream
     带缓冲区的字符流: BufferedReader / PrintWriter(打印流)

     转换流: OutputStreamWriter / InputStreamReader

 

暑期编程PK赛 得CSDN机械键盘等精美礼品!
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1017473.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号