Java基础——File类与IO流

File类

java.lang.Object
java.io.File

java把电脑中的文件,文件夹(目录)封装成了一个File类,我们可以使用File类对文件和文件夹进行操作

可以使用File类的方法去:

​ 创建一个文件/文件夹

​ 删除文件/文件夹

​ 获取文件/文件夹

​ 判断文件/文件夹是否存在

​ 对文件夹进行遍历

​ 获取文件的大小

File类是一个与系统无关的类,任何操作系统都可以使用这个类中的方法

重点:记住3个单词

  1. file:文件
  2. directory:文件夹/目录
  3. path:路径

File类的静态成员变量

字段摘要
static String pathSeparator 与系统有关的路径分隔符,为了方便,它被表示为一个字符串。
static char pathSeparatorChar 与系统有关的路径分隔符。
static String separator 与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。
static char separatorChar 与系统有关的默认名称分隔符。
public class DemosFile {
    public static void main(String[] args) {
        String pathSeparator = File.pathSeparator;
        System.out.println(pathSeparator);//文件名称分隔符:windows:反斜杠 Linux:正斜杠/
        char pathSeparatorChar = File.pathSeparatorChar;
        System.out.println(pathSeparatorChar);//文件名称分隔符:windows:反斜杠 Linux:正斜杠/

        String separator = File.separator;
        System.out.println(separator);//路径分隔符 windows:分号    Linux:冒号
        char separatorChar = File.separatorChar;
        System.out.println(separatorChar);//路径分隔符 windows:分号    Linux:冒号


        /*操作路径不能写死了
        *   例如:
        *       C:\Users\98398\Desktop\我的MarkDown文件     Windows
        *       C:/Users/98398/Desktop/我的MarkDown文件     Linnux
        *正确写法:
        *       "C:"+File.separator+"User"+File.separator+"a"+File.separator+"a.png"
        *
        * */
    }
}


绝对路径和相对路径

路径:

​ 绝对路径:是一个完整的路径

​ 以盘符开始的路径

​ 相对路径:是一个简化的路径

​ 相对指的是相对于当前项目的根目录

​ 如果使用当前项目的根目录,路径可以简化书写(可以省略根目录不写)

​ 注意:

	1. 路径不区分大小写
	2. 路径中文件名称分隔符Windows使用反斜杠,反斜杠是转义字符,两个反斜杠代表一个普通的反斜杠

File类的构造方法

import java.io.File;

public class DemosFile2 {
    /**
     * File类的构造方法
     */
    public static void main(String[] args) {
        show1();
        show2("C:\\","c.txt ");
        show3();

    }

    private static void show3() {
        File parent = new File("C:\\");
        File file3 = new File(parent, "d.java");
        System.out.println(file3);
    }

    private static void show2(String a,String b) {
        File file2 = new File(a, b);
        System.out.println(file2);
    }

    private static void show1() {
        File file1 = new File("C:\\Users\\98398\\Desktop\\我的MarkDown文件\\a.txt");
        System.out.println(file1);

        File file2 = new File("C:\\Users\\98398\\Desktop\\我的MarkDown文件");
        System.out.println(file2);

        File file3 = new File("b.txt");
        System.out.println(file3);
    }
}

File类获取功能的方法

方法摘要
boolean canExecute()
测试应用程序是否可以执行此抽象路径名表示的文件。
boolean canRead()
测试应用程序是否可以读取此抽象路径名表示的文件。
boolean canWrite()
测试应用程序是否可以修改此抽象路径名表示的文件。
int compareTo(File pathname)
按字母顺序比较两个抽象路径名。
boolean createNewFile()
当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件。

static File createTempFile(String prefix, String suffix)
在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。
static File createTempFile(String prefix, String suffix, File directory)
在指定目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。
boolean delete()
删除此抽象路径名表示的文件或目录。

void deleteOnExit()
在虚拟机终止时,请求删除此抽象路径名表示的文件或目录。
boolean equals(Object obj)
测试此抽象路径名与给定对象是否相等。
boolean exists()
测试此抽象路径名表示的文件或目录是否存在。

File getAbsoluteFile()
返回此抽象路径名的绝对路径名形式。
String getAbsolutePath()
返回此抽象路径名的绝对路径名字符串。

File getCanonicalFile()
返回此抽象路径名的规范形式。
String getCanonicalPath()
返回此抽象路径名的规范路径名字符串。
long getFreeSpace()
返回此抽象路径名指定的分区中未分配的字节数。
String getName()
返回由此抽象路径名表示的文件或目录的名称。

String getParent()
返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null。
File getParentFile()
返回此抽象路径名父目录的抽象路径名;如果此路径名没有指定父目录,则返回 null。
String getPath()
将此抽象路径名转换为一个路径名字符串。

long getTotalSpace()
返回此抽象路径名指定的分区大小。
long getUsableSpace()
返回此抽象路径名指定的分区上可用于此虚拟机的字节数。
int hashCode()
计算此抽象路径名的哈希码。
boolean isAbsolute()
测试此抽象路径名是否为绝对路径名。
boolean isDirectory()
测试此抽象路径名表示的文件是否是一个目录。

boolean isFile()
测试此抽象路径名表示的文件是否是一个标准文件。

boolean isHidden()
测试此抽象路径名指定的文件是否是一个隐藏文件。
long lastModified()
返回此抽象路径名表示的文件最后一次被修改的时间。
long length()
返回由此抽象路径名表示的文件的长度。

String[] list()
返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。

String[] list(FilenameFilter filter)
返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录。
File[] listFiles()
返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。

File[] listFiles(FileFilter filter)
返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录。
File[] listFiles(FilenameFilter filter)
返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录。
static File[] listRoots()
列出可用的文件系统根。
boolean mkdir()
创建此抽象路径名指定的目录。

boolean mkdirs()
创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。

boolean renameTo(File dest)
重新命名此抽象路径名表示的文件。
boolean setExecutable(boolean executable)
设置此抽象路径名所有者执行权限的一个便捷方法。
boolean setExecutable(boolean executable, boolean ownerOnly)
设置此抽象路径名的所有者或所有用户的执行权限。
boolean setLastModified(long time)
设置此抽象路径名指定的文件或目录的最后一次修改时间。
boolean setReadable(boolean readable)
设置此抽象路径名所有者读权限的一个便捷方法。
boolean setReadable(boolean readable, boolean ownerOnly)
设置此抽象路径名的所有者或所有用户的读权限。
boolean setReadOnly()
标记此抽象路径名指定的文件或目录,从而只能对其进行读操作。
boolean setWritable(boolean writable)
设置此抽象路径名所有者写权限的一个便捷方法。
boolean setWritable(boolean writable, boolean ownerOnly)
设置此抽象路径名的所有者或所有用户的写权限。
String toString()
返回此抽象路径名的路径名字符串。
URI toURI()
构造一个表示此抽象路径名的 file: URI。
URL toURL()
已过时。 此方法不会自动转义 URL 中的非法字符。建议新的代码使用以下方式将抽象路径名转换为 URL:首先通过 toURI 方法将其转换为 URI,然后通过 URI.toURL 方法将 URI 装换为 URL。


import java.io.File;

public class DemosFile3 {
    /**
     * String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串。
     * String getName() 返回由此抽象路径名表示的文件或目录的名称。
     * String getPath() 将此抽象路径名转换为一个路径名字符串。
     * long length() 返回由此抽象路径名表示的文件的长度。
     */
    public static void main(String[] args) {
        show1();
        System.out.println("———————————————————————————————————");
        show2();
        System.out.println("———————————————————————————————————");
        show3();
        System.out.println("———————————————————————————————————");
        show4();

    }
/*long length() 返回由此抽象路径名表示的文件的长度。
* 此方法获取的是构造方法中指定的文件的大小,以字节为单位
* 注意:
*       1.只能获取文件的大小,无法获取文件夹的大小
*       (因为计算机中文件夹的大小属性是没有值的
*       我们可以通过属性去查看文件夹的大小,但是看到的大小值其实是该文件夹里所有文件的大小总和)
*
*       2.如果构造方法中给出的路径不存在,那么length()方法返回的就是0*/
    private static void show4() {
        File file1 = new File("C:\\Users\\98398\\Desktop\\我的截图\\hahaahahah.jpg");//真实存在的文件(绝对路径)
        long length1 = file1.length();//获取到的是文件大小
        System.out.println(length1);

        File file2 = new File("pom.xml");//真实存在的文件(相对路径)
        long length2 = file2.length();//获取到的是文件大小
        System.out.println(length2);

        File file3 = new File("wuwuwuwuwu.jpg");//不存在的文件
        long length3 = file3.length();//文件不存在,获取到的返回值是0
        System.out.println(length3);

        File file4 = new File("E:\\IdeaProjects\\spring-study\\poker");//真实存在的文件夹
        long length4 = file4.length();//文件夹存在,获取到的返回值是0
        System.out.println(length4);

        File file5 = new File("E:\\IdeaProjects\\spring-study\\poker");//不存在的文件夹
        long length5 = file5.length();//文件夹不存在,获取到的返回值是0
        System.out.println(length5);


    }

    /*String getName() 返回由此抽象路径名表示的文件或目录的名称。
* 此方法获取的是构造方法中传递的路径
* getName()方法返回的是路径的结尾部分*/
    private static void show3() {
        File file1 = new File("E:\\IdeaProjects\\spring-study\\a.txt");//结尾是文件名(绝对路径)
        String name1 = file1.getName();//获取到的是文件名
        System.out.println(name1);

        File file2 = new File("E:\\IdeaProjects\\spring-study");//结尾是文件夹名(绝对路径)
        String name2 = file2.getName();//获取到的是文件夹名
        System.out.println(name2);

        File file3 = new File("a.txt");//结尾是文件夹名(相对路径)
        String name3 = file3.getName();//获取到的是文件夹名
        System.out.println(name3);
    }

    /*String getPath() 将此抽象路径名转换为一个路径名字符串。
* 此方法获取的是构造方法中传递的路径
* 路径是什么,getPath()方法就返回什么
*
* toString调用的就是getPath()方法*/
    private static void show2() {
        File file1 = new File("E:\\IdeaProjects\\spring-study\\a.txt");//绝对路径
        String path1 = file1.getPath();//获取到的就是绝对路径
        System.out.println(path1);

        File file2 = new File("a.txt");//相对路径
        String path2 = file2.getPath();//获取到的就是相对路径
        System.out.println(path2);

        System.out.println(file1.toString());//toString调用的就是getPath()方法
        System.out.println(file2.toString());//toString调用的就是getPath()方法
    }

    /*String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串。
* 此方法获取的是构造方法中传递的路径
* 无论路径是绝对路径还是相对路径,getAbsolutePath()方法返回的都是 绝对路径 */
    private static void show1() {
        File file1 = new File("E:\\IdeaProjects\\spring-study\\a.txt");//绝对路径
        String absolutePath1 = file1.getAbsolutePath();//获取到的是绝对路径
        System.out.println(absolutePath1);

        File file2 = new File("a.txt");//相对路径
        String absolutePath2 = file2.getAbsolutePath();//获取到的还是绝对路径
        System.out.println(absolutePath2);
    }



}

运行结果:


File类判断功能的方法

boolean isDirectory()
测试此抽象路径名表示的文件是否是一个目录。

boolean isFile()
测试此抽象路径名表示的文件是否是一个标准文件。

boolean exists()
测试此抽象路径名表示的文件或目录是否存在。

import java.io.File;

public class DemosFile4 {
    /*
File类判断功能的方法
    boolean exists() 测试此抽象路径名表示的文件或目录是否存在。
    boolean isDirectory() 测试此抽象路径名表示的文件是否是一个目录。
    boolean isFile() 测试此抽象路径名表示的文件是否是一个标准文件。


*/
    public static void main(String[] args) {
        show1();
        System.out.println("———————————————————————————————————");
        show2();
    }

    private static void show3() {

    }

    /**
     * boolean isDirectory() 测试此抽象路径名表示的文件是否是一个目录。
     *  用于判断构造方法中路径是否以文件夹结尾
     *      是:true
     *      否:false
     *
     *boolean isFile() 测试此抽象路径名表示的文件是否是一个标准文件。
     *  用于判断构造方法中路径是否以文件结尾
     *      是:true
     *      否:false
     *
     *      注意:
     *          电脑硬盘中只有文件或文件夹,所以两个方法是互斥的
     *          这两个方法的使用前提是,路径必须是真实存在的,否则都返回false
     */
    private static void show2() {
        File file1 = new File("E:\\IdeaProjects\\spring-studyxxxx");//不存在的绝对路径
        System.out.println(file1.isDirectory());//false
        System.out.println(file1.isFile());//false

        //代码优化
        //先判断路径存不存在,如果路径不存在就没有必要获取
        if(file1.exists()){//路径不存在,不执行下面两行代码
            System.out.println(file1.isDirectory());
            System.out.println(file1.isFile());
        }

        File file2 = new File("E:\\IdeaProjects\\spring-study");//真实存在的绝对路径,结尾是文件夹
        if(file2.exists()){
            System.out.println(file2.isDirectory());//结尾是文件夹,所以返回值是true
            System.out.println(file2.isFile());//结尾是文件夹不是文件,所以返回值是false
        }

        File file3 = new File("E:\\IdeaProjects\\spring-study\\FileAndIO\\pom.xml");//真实存在的绝对路径,结尾是文件
        if(file3.exists()){
            System.out.println(file3.isDirectory());//结尾是文件不是文件夹,所以返回值是false
            System.out.println(file3.isFile());//结尾是文件,所以返回值是true
        }



    }

    /**
     * boolean exists() 测试此抽象路径名表示的文件或目录是否存在。
     * 用于判断构造方法中路径是否存在
     * 返回值类型是boolean
     * 存在:true
     * 不存在:false
     */
    private static void show1() {
        File file1 = new File("E:\\IdeaProjects\\spring-study");//真实存在的绝对路径
        boolean exists1 = file1.exists();//存在则返回true
        System.out.println(exists1);

        File file2 = new File("E:\\IdeaProjects\\spring-studyxxxx");//不存在的绝对路径
        boolean exists2 = file2.exists();//不存在则返回false
        System.out.println(exists2);

        File file3 = new File("pom.xml");//真实存在的相对路径
        boolean exists3 = file3.exists();//存在则返回true
        System.out.println(exists3);

        File file4 = new File("pomxxx.xml");//不存在的相对路径
        boolean exists4 = file4.exists();//不存在则返回false
        System.out.println(exists4);
    }
}

运行结果:


File类创建和删除功能的方法

boolean createNewFile()
当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件。

boolean delete()
删除此抽象路径名表示的文件或目录。

boolean mkdir()
创建此抽象路径名指定的目录。

boolean mkdirs()
创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。

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

public class DemosFile5 {
    /*
    boolean createNewFile() 当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件。
    boolean delete() 删除此抽象路径名表示的文件或目录。
    boolean mkdir() 创建此抽象路径名指定的目录。
    boolean mkdirs() 创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。


    */
    public static void main(String[] args) throws IOException {
        show1();
        show2();
        show3();
    }
/*
* boolean delete() 删除此抽象路径名表示的文件或目录。
* 此方法,可以删除构造方法路径中的文件也可以删除构造方法路径中的文件夹
* 返回值:
*   true:文件/文件夹删除成功,返回true
*   false:文件夹中有内容,就不会删除文件文件夹,返回false;或者构造方法中路径是错的,路径不存在,就删除不了,也会返回false
* 注意事项:
*   delete方法是直接从硬盘删除文件/文件夹,不会经过回收站,所以使用此方法要谨慎,避免删除重要文件导致不必要的损失
* */
    private static void show3() throws IOException {
        File file1 = new File("FileAndIO\\src\\main\\java\\a");//构造方法路径所表示的文件/文件夹就是要删除的对象
        boolean b1 = file1.delete();//a文件夹被删除
        System.out.println("b1:"+b1);//true

        File file2 = new File("FileAndIO\\src\\main\\java\\a.txt");//构造方法路径所表示的文件/文件夹就是要删除的对象
        boolean b2 = file2.delete();//a.txt文件被删除
        System.out.println("b2:"+b2);//true

        File file3 = new File("FileAndIO\\src\\main\\java\\asasas.txt");//构造方法路径所表示的文件/文件夹就是要删除的对象
        boolean b3 = file3.delete();//文件不存在或路径错误,删除失败
        System.out.println("b3:"+b3);//false

        //先再abc.txt文件夹里放点东西,我随便创建了一个.java文件
        File file4 = new File("FileAndIO\\src\\main\\java\\abc.txt\\a.txt");//绝对路径
        System.out.println(file4.createNewFile());//true

        File file5 = new File("FileAndIO\\src\\main\\java\\abc.txt");//构造方法路径所表示的文件/文件夹就是要删除的对象
        boolean b5 = file5.delete();//文件夹中有内容,无法删除文件夹
        System.out.println("b5:"+b5);//false

    }

    /*  boolean mkdir() 创建此抽象路径名指定的目录。
        boolean mkdirs() 创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。
        创建文件的路径和名称再构造方法中给出(构造方法的参数)
         * 返回值:
         *  true:文件夹不存在,不会创建,返回true
         *  false:文件夹存在,不会创建,返回false
         * 注意:
         *      1.此方法只能创建文件夹,不能创建文件
        */
    private static void show2() {
        File file1 = new File("FileAndIO\\src\\main\\java\\a");//只要路径存在,文件夹名字唯一,就能创建成功
        boolean mkdir1 = file1.mkdir();
        System.out.println("mkdir1:"+mkdir1);//true

        File file2 = new File("FileAndIO\\src\\main\\java\\a\\b\\c\\d");//无法创建一个有一个嵌套的文件夹
        boolean mkdir2 = file2.mkdir();
        System.out.println("mkdir2:"+mkdir2);//false

        File file3 = new File("FileAndIO\\src\\main\\java\\abc.txt");//创建的还是一个文件夹,abc.txt是文件夹的名字
        boolean mkdir3 = file3.mkdir();
        System.out.println("mkdir3:"+mkdir3);//true

        File file4 = new File("Fil\\ccc.txt");//路径错误,无法创建,但是这个方法没有异常抛出
        boolean mkdir4 = file4.mkdir();
        System.out.println("mkdir4:"+mkdir4);//false



    }

    /**
     *boolean createNewFile() 当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件。
     * 创建文件的路径和名称再构造方法中给出(构造方法的参数)
     * 返回值:
     *  true:文件不存在,不会创建,返回true
     *  false:文件存在,不会创建,返回false
     * 注意:
     *      1.此方法只能创建文件,不能创建文件夹
     *      2.创建文件的路径必须存在,否则会抛出异常
     */
    private static void show1() throws IOException {
        File file1 = new File("E:\\IdeaProjects\\spring-study\\FileAndIO\\src\\main\\java\\a.txt");//绝对路径
        boolean b1 = file1.createNewFile();
        System.out.println("b1:"+b1);//true

        File file2 = new File("FileAndIO\\src\\main\\java\\b.txt");//绝对路径
        System.out.println(file2.createNewFile());//true
    }
}

运行结果:


File类的目录的遍历功能

String[] list()
返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。

File[] listFiles()
返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。

import java.io.File;

public class DemosFile6 {
    /*
    String[] list()
            返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。
    File[] listFiles()
            返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。

            注意:
                list方法和listFiles方法遍历的是构造方法中给出的目录
                如果构造方法中给出的目录的路径不存在,就会抛出空指针异常
                如果构造方法中给出的路径不是一个目录,也会抛出空指针异常

          */
    public static void main(String[] args) {
        show1();
        show2();
    }
/*File[] listFiles()
            返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。
        此方法会遍历构造方法中给出的目录,会获取目录中所有文件/文件夹的名称,把获取到的所有文件/文件夹封装为File对象并存储到File数组中
            */
    private static void show2() {
        File file1 = new File("E:\\IdeaProjects\\spring-study\\FileAndIO\\src\\main\\java");
        File[] files = file1.listFiles();
        System.out.println(files);
        for (File file : files) {
            System.out.println(file);
        }
    }

    /*String[] list()
                返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。
      此方法会遍历构造方法中给出的目录,会获取目录中所有文件/文件夹的名称,把获取到的多个名称存储到一个String类型的数组中*/
    private static void show1() {
        File file1 = new File("E:\\IdeaProjects\\spring-study\\FileAndIO\\src\\main\\java");
        String[] list1 = file1.list();
        System.out.println(list1);

        //遍历打印list1数组
        for (String s : list1) {
            System.out.println(s);
        }
    }
}

运行结果:


IO流

I:input 输入(读取)->把硬盘中的数据,读取到内存中使用

O:output 输出(写入)->把内存中的数据,写入到硬盘中保存

流数据(字符,字节):1字符=2字节,1字节=8位

字节流

一切皆是字节

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

字节输出流【OutputStream】

它是所有字节输出流的一个最顶层的父类,它是一个抽象类,里面定义了所有字节流都可以使用的一些公共方法。

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


FilterOutputStream:文件字节输出流

作用:把内存中的数据写入到硬盘的文件中

构造方法摘要
FileOutputStream(File file)
创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
FileOutputStream(File file, boolean append)
创建一个向指定 File 对象表示的文件中写入数据的文件输出流。

FileOutputStream(FileDescriptor fdObj)
创建一个向指定文件描述符处写入数据的输出文件流,该文件描述符表示一个到文件系统中的某个实际文件的现有连接。
FileOutputStream(String name)
创建一个向具有指定名称的文件中写入数据的输出文件流。
FileOutputStream(String name, boolean append)
创建一个向具有指定 name 的文件中写入数据的输出文件流。


其中常用的两个构造方法:

FileOutputStream(File file)
创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
FileOutputStream(String name)
创建一个向具有指定名称的文件中写入数据的输出文件流。

参数:数据写入的位置/目的地,可以是一个文件路径,也可以是一个文件

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

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

构造方法的作用:

	1. 创建一个FileOutputStream对象
	2. 会根据构造方法中传递的文件/文件路径,创建一个空的文件
	3. 会把FileOutputStream对象指向创建好的文件

怎么把单个字节由内存中写入到硬盘中?

import java.io.FileOutputStream;
import java.io.IOException;

public class DemosFile8 {
    public static void main(String[] args) throws IOException {
        //1.创建一个FileOutputStream对象,构造方法中传入要写入数据的目的地
        FileOutputStream fos = new FileOutputStream("E:\\IdeaProjects\\spring-study\\FileAndIO\\src\\main\\java\\c.txt");
        //2.调用FileOutputStream对象中的方法write,把数据写入指定文件中
        //pubilc abstract  void write(int b)将指定的字节写入此输出流。
        fos.write(97);//a
        //3.释放资源(流会占用内存,使用完毕要释放内存,提高程序效率)
        fos.close();
    }
}


怎么把多个字节由内存中写入到硬盘中?

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;

public class DemosFile9 {
    public static void main(String[] args) throws IOException {
        //1.创建一个FileOutputStream对象,构造方法中传入要写入数据的目的地
        FileOutputStream fos = new FileOutputStream(new File("FileAndIO\\src\\main\\java\\d.txt"));
        //2.创建一个byte[]数组,供write(byte[] b)方法使用
        byte[] bytes1 = new byte[]{65,66,67,68,69};//ABCDE
        byte[] bytes2 = new byte[]{-65,-66,-67,68,69};//烤紻E
        /*3.调用FileOutputStream对象中的方法write(byte[] b),把多个字节数据写入指定文件中
        void write(byte[] b)
                  将 b.length 个字节从指定的 byte 数组写入此输出流。
                  注意:
                        如果写入的第一个字节是正数(0~127),那么显示的时候会查询ASCII表
                        如果写的第一个字节是负数,那么第一个字节和第二个字节会组成一个中文显示,查询系统默认码表(GBK)*/
        fos.write(bytes1);
        fos.write(bytes2);

        /*void write(byte[] b, int off, int len)
        将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。
            int off:数组的开始索引
            int len:写几个字节
        */
        fos.write(bytes1,0,3);//ABC
        fos.write(bytes1,0,2);//AB
        fos.write(bytes1,1,4);//BCDE
//        fos.write(bytes1,1,5);//IndexOutOfBoundsException索引越界异常(上面三行代码仍然运行成功)
//        fos.write(bytes1,0,3);//由于上面一行代码IndexOutOfBoundsException索引越界异常,所以下面的代码就不执行了
        //写入字符串的方法:byte[] getBytes() 把字符串转换成为字节数组
        byte[] bytes3 = "你好世界".getBytes();
        System.out.println(Arrays.toString(bytes3));
        fos.write(bytes3);
        /*在文件中显示100,需要写3个字节
        fos.write(49);
        fos.write(48);
        fos.write(48);*/
        //4.释放资源(流会占用内存,使用完毕要释放内存,提高程序效率)
        fos.close();
    }
}


字节输出流的续写和换行

给文件续写:使用两个参数的构造方法

  • FileOutputStream(File file, boolean append)
    创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
  • FileOutputStream(String name, boolean append)
    创建一个向具有指定 name 的文件中写入数据的输出文件流。

参数:

​ String name,File file:写入数据的目的地

​ boolean append:追加写开关;返回值:true->创建对象不会覆盖原文件,继续在文件的末尾追加写数据

​ false->创建一个新文件,覆盖原文件

import java.io.FileOutputStream;
import java.io.IOException;

/*
* 给文件续写:使用两个参数的构造方法
*   FileOutputStream(File file, boolean append)
          创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
*   FileOutputStream(String name, boolean append)
          创建一个向具有指定 name 的文件中写入数据的输出文件流。
          * 参数:
      String name,File file:写入数据的目的地
      boolean append:追加写开关;
      * 返回值:true->创建对象不会覆盖原文件,继续在文件的末尾追加写数据
               false->创建一个新文件,覆盖原文件
* */
public class DemosFile10 {
    public static void main(String[] args) throws IOException {
        //1.创建一个FileOutputStream对象,构造方法中传入要写入数据的目的地
        FileOutputStream fos = new FileOutputStream("FileAndIO\\src\\main\\java\\d.txt",true);
        for (int i = 0; i < 10; i++) {
            fos.write("\r\n".getBytes());//每次写入数据并换行
            fos.write("追写的数据".getBytes());
        }
        fos.close();
    }
}


方法摘要

int available()
返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)的估计字节数。
void close()
关闭此输入流并释放与该流关联的所有系统资源。
void mark(int readlimit)
在此输入流中标记当前的位置。
boolean markSupported()
测试此输入流是否支持 mark 和 reset 方法。
abstract int read()
从输入流中读取数据的下一个字节。
int read(byte[] b)
从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。
int read(byte[] b, int off, int len)
将输入流中最多 len 个数据字节读入 byte 数组。
void reset()
将此流重新定位到最后一次对此输入流调用 mark 方法时的位置。
long skip(long n)
跳过和丢弃此输入流中数据的 n 个字节。


字节输入流FileInputStream类

构造方法摘要

FileInputStream(File file)
通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
FileInputStream(FileDescriptor fdObj)
通过使用文件描述符 fdObj 创建一个 FileInputStream,该文件描述符表示到文件系统中某个实际文件的现有连接。
FileInputStream(String name)
通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。

参数:是读取文件的数据源

  • String name:文件的路径
  • File file:文件

构造方法的作用:

  • 会创建一个FileInputStream对象
  • 会把FileInputStream对象指向构造方法中要读取的文件

字节输入流的使用步骤--3步(重点)
1.创建一个FileInputStream对象,构造方法中绑定要读取的数据源
2.使用FileInputStream对象中的方法read,读取文件
3.释放资源

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

/*java.io.InputStream 字节输入流
*   此抽象类是字节输入流的所以类的父类(超类)
*
* 定义了所有子类共性的方法:
*   int read()从输入流中读取数据的下一个字节
*   int read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中
*   void close() 关闭此输入流并释放与该流关联的所有资源
*
* java.io.FileInputStream extends InputStream
* FileInputStream:文件字节输入流
* 作用:把硬盘文件中的数据,读取到内存中使用
*
* 构造方法
*   构造方法摘要
        FileInputStream(String name)  通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。
        FileInputStream(File file)  通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
        参数:是读取文件的数据源
        *   String name:文件的路径
        *   File file:文件
        构造方法的作用:
        *   1.会创建一个FileInputStream对象
        *   2.会把FileInputStream对象指向构造方法中要读取的文件
        读取数据的原理(硬盘->内存)
            java程序-->JVM-->OS-->OS读取数据的方法-->读取文件
        字节输入流的使用步骤--3步(重点)
            1.创建一个FileInputStream对象,构造方法中绑定要读取的数据源
            2.使用FileInputStream对象中的方法read,读取文件
            3.释放资源
* */

public class DemosFile11 {
    public static void main(String[] args) throws IOException {
        //1.创建一个FileOutputStream对象,构造方法中传入要写入数据的目的地
        FileInputStream fos = new FileInputStream("FileAndIO\\src\\main\\java\\c.txt");
        int len = fos.read();
        System.out.println(len);//65

        len = fos.read();
        System.out.println(len);//66

        len = fos.read();
        System.out.println(len);//67

        len = fos.read();
        System.out.println(len);//-1    表示读取结束,文件中数据读完了

        len = fos.read();
        System.out.println(len);//数据读完之后再读一次,还是-1
        //释放资源
        fos.close();
    }
}

代码优化:

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

/*java.io.InputStream 字节输入流
*   此抽象类是字节输入流的所以类的父类(超类)
*
* 定义了所有子类共性的方法:
*   int read()从输入流中读取数据的下一个字节
*   int read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中
*   void close() 关闭此输入流并释放与该流关联的所有资源
*
* java.io.FileInputStream extends InputStream
* FileInputStream:文件字节输入流
* 作用:把硬盘文件中的数据,读取到内存中使用
*
* 构造方法
*   构造方法摘要
        FileInputStream(String name)  通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。
        FileInputStream(File file)  通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
        参数:是读取文件的数据源
        *   String name:文件的路径
        *   File file:文件
        构造方法的作用:
        *   1.会创建一个FileInputStream对象
        *   2.会把FileInputStream对象指向构造方法中要读取的文件
        读取数据的原理(硬盘->内存)
            java程序-->JVM-->OS-->OS读取数据的方法-->读取文件
        字节输入流的使用步骤--3步(重点)
            1.创建一个FileInputStream对象,构造方法中绑定要读取的数据源
            2.使用FileInputStream对象中的方法read,读取文件
            3.释放资源
* */

public class DemosFile11 {
    public static void main(String[] args) throws IOException {
        //1.创建一个FileInputStream对象,构造方法中绑定要读取的数据源
        FileInputStream fos = new FileInputStream("FileAndIO\\src\\main\\java\\c.txt");
        /*int len = fos.read();
        System.out.println(len);//65

        len = fos.read();
        System.out.println(len);//66

        len = fos.read();
        System.out.println(len);//67

        len = fos.read();
        System.out.println(len);//-1    表示读取结束,文件中数据读完了

        len = fos.read();
        System.out.println(len);//数据读完之后再读一次,还是-1
*/
        /*上面的代码都是重复代码,可以用循环语句来优化代码*/
        //因为不知道读取多少次擦磁能读完文件,所以用while循环
        int len = 0;
        while ((len = fos.read())!=-1){
            System.out.print((char) len);//把读到的结果转换成字符表示出来
        }
        
        //释放资源
        fos.close();
    }
}

字节输入流一次读取多个字节

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;

/*字节输入流一次读取多个字节的方法:
    int read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中。
  明确两件事情:
    1.方法的参数byte[]的作用?
    2.方法返回值int是什么?


 * */

public class DemosFile12 {
    public static void main(String[] args) throws IOException {
        //1.创建一个FileInputStream对象,构造方法中绑定要读取的数据源
        FileInputStream fis = new FileInputStream("FileAndIO\\src\\main\\java\\c.txt");
        //2.使用FileInputStream对象中的read(byte[] b)方法读取文件
        //int read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中

        /*byte[] bytes = new byte[2];
        int len = fis.read(bytes);
        System.out.println(len);//2
        System.out.println(Arrays.toString(bytes));//[65, 66]
        System.out.println(new String(bytes));//AB

        len = fis.read(bytes);
        System.out.println(len);//2
        System.out.println(new String(bytes));//CD
        len = fis.read(bytes);
        System.out.println(len);//1
        System.out.println(new String(bytes));//ED
        len = fis.read(bytes);
        System.out.println(len);//-1
        System.out.println(new String(bytes));//ED
        len = fis.read(bytes);
        System.out.println(len);//-1
        System.out.println(new String(bytes));//ED
        */
        //循环优化以上代码,因为不知道读取多少次擦磁能读完文件,所以用while循环
        byte[] bytes = new byte[1024];
        int len = 0;//记录每次读取的有效字节的个数
        while ((len = fis.read(bytes))!=-1){
            System.out.println(new String(bytes));//这种转换字符串的方法会多很多空格,推荐使用下面一种方法
            System.out.println(new String(bytes,0,len));
        }
        //释放资源
        fis.close();
    }
}


字节流完成复制文件操作

原理:一读一写

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



public class DemosFileCopy {
    public static void main(String[] args) throws IOException {
        long start = System.currentTimeMillis();//开始计时(用来计算程序执行时间)
        //注意:读的文件是什么格式,写的目的地就要是什么格式的文件,写的目的地不能是文件夹
        FileInputStream fis = new FileInputStream("C:\\Users\\98398\\Desktop\\我的截图\\wallhaven-rddz6w.jpg");
        FileOutputStream fos = new FileOutputStream("E:\\IdeaProjects\\spring-study\\FileAndIO\\src\\main\\java\\abc.txt\\2.jpg",true);
        int len = 0;
        byte[] bytes = new byte[10240];
        while ((len = fis.read(bytes))!=-1){
            fos.write(bytes,0,len);
        }
        //释放资源(先关闭写的,后关闭读的)
        fos.close();
        fis.close();
        long end = System.currentTimeMillis();//结束计时(用来计算程序执行时间)
        System.out.println("复制图片耗时"+(end-start)+"ms");
    }
}

字符流Reader

3个共性成员方法

  • int read() 读取单个字符
  • int read(char[] cbuf) 将字符读入数组
  • void close() 关闭该流并释放与之关联的所有资源

java.lang.Object
继承者 java.io.Reader
继承者 java.io.InputStreamReader
继承者 java.io.FileReader

构造方法

FileReader(File file)
在给定从中读取数据的 File 的情况下创建一个新 FileReader。
FileReader(FileDescriptor fd)
在给定从中读取数据的 FileDescriptor 的情况下创建一个新 FileReader。
FileReader(String fileName)
在给定从中读取数据的文件名的情况下创建一个新 FileReader。


字符流读取硬盘中数据

字符输入流FileReader

使用步骤

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


public class DemosFile13 {
    public static void main(String[] args) throws IOException {
        //1.创建一个FileReader对象,构造方法中绑定要读取的数据源
        FileReader fr = new FileReader("FileAndIO\\src\\main\\java\\abc.txt\\a.txt");
        //2.使用FileReader对象中的read()方法读取文件【一次读取一个字符】
/*        int len = 0;
        while ((len = fr.read())!=-1){
            System.out.println((char) len);
        }*/

        //一次读取多个字符:int read(char[] cbuf) 将字符读入数组【一次读取多个字符】
        int len = 0;
        char[] chars = new char[1024];
        while ((len = fr.read(chars))!=-1){
            System.out.println(new String(chars,0,len));
        }


        //3.释放资源
        fr.close();
    }
}

字符输出流Writer

方法摘要
Writer append(char c)
将指定字符添加到此 writer。
Writer append(CharSequence csq)
将指定字符序列添加到此 writer。
Writer append(CharSequence csq, int start, int end)
将指定字符序列的子序列添加到此 writer.Appendable。
abstract void close()
关闭此流,但要先刷新它。
abstract void flush()
刷新该流的缓冲。
void write(char[] cbuf)
写入字符数组。
abstract void write(char[] cbuf, int off, int len)
写入字符数组的某一部分。
void write(int c)
写入单个字符。
void write(String str)
写入字符串。
void write(String str, int off, int len)
写入字符串的某一部。


文件字符输出流FileWriter

java.lang.Object
继承者 java.io.Writer
继承者 java.io.OutputStreamWriter
继承者 java.io.FileWriter

构造方法摘要

FileWriter(File file)
根据给定的 File 对象构造一个 FileWriter 对象。
FileWriter(File file, boolean append)
根据给定的 File 对象构造一个 FileWriter 对象。
FileWriter(FileDescriptor fd)
构造与某个文件描述符相关联的 FileWriter 对象。
FileWriter(String fileName)
根据给定的文件名构造一个 FileWriter 对象。
FileWriter(String fileName, boolean append)
根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象。


1.FileWriter(File file)
根据给定的 File 对象构造一个 FileWriter 对象。
2.FileWriter(String fileName)
根据给定的文件名构造一个 FileWriter 对象。

参数:

  • String fileName:文件的路径
  • File file:是一个文件

构造方法的作用

  1. 创建一个FileWriter对象
  2. 会根据构造方法中传递的文件/文件的路径,创建一个文件
  3. 会把FileWriter对象指向创建好的文件

字符输出流Writer的使用步骤

  1. 创建FileWriter对象,构造方法中绑定要写入数据的目的地
  2. 使用FileWriter中的方法Writer,把数据写入到内存缓冲区中【有一个把字符转换为字节的过程】【跟字节输出流直接把数据写入文件中有所不同】
  3. 使用FileWriter中的方法flush,把内存缓冲区中的数据,刷新到文件中
  4. 释放资源【会先把内存缓冲区中的数据刷新到文件中】

写入单个字符

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


public class DemosFile13 {
    public static void main(String[] args) throws IOException {
        //1.创建一个FileWriter对象,构造方法中绑定要读取的数据源
        FileWriter fw = new FileWriter("FileAndIO\\src\\main\\java\\abc.txt\\e.txt");
        //2.使用FileWriter中的方法Writer,把数据写入到内存缓冲区中【有一个==把字符转换为字节==的过程】【跟字节输出流直接把数据写入文件中有所不同】
        fw.write(97);//a
        //3.使用FileWriter中的方法flush,把内存缓冲区中的数据,刷新到文件中
        fw.flush();//【刷新缓冲区】
        
        //4.释放资源 l 
        fw.close();
    }
}

写入多个字符【字符输出流写数据得其它方法】

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

/*
void write(char[] cbuf)
          写入字符数组。
abstract  void write(char[] cbuf, int off, int len)
          写入字符数组的某一部分。
 void write(int c)
          写入单个字符。
 void write(String str)
          写入字符串。
 void write(String str, int off, int len)
          写入字符串的某一部分。

 */
public class DemosFile13 {
    public static void main(String[] args) throws IOException {
        //1.创建一个FileWriter对象,构造方法中绑定要读取的数据源
        FileWriter fw = new FileWriter("FileAndIO\\src\\main\\java\\abc.txt\\e.txt");
        //2.使用FileWriter中的方法Writer,把数据写入到内存缓冲区中【有一个==把字符转换为字节==的过程】【跟字节输出流直接把数据写入文件中有所不同】
        //void write(char[] cbuf)
        char[] chars = {'a', 'b', 'c', 'd', 'e', 'f', 'g'};
        fw.write(chars);
        //3.使用FileWriter中的方法flush,把内存缓冲区中的数据,刷新到文件中【刷新缓冲区】
        fw.flush();//abcdefg
        //刷新缓冲区后,还可以继续写入数据
        fw.write(chars);//abcdefg
        //abstract  void write(char[] cbuf, int off, int len)写入字符数组的某一部分。
        fw.write(chars,2,2);//cd
        //void write(String str)写入字符串。
        fw.write("我是字符串");
        //void write(String str, int off, int len)写入字符串的某一部分。
        fw.write("我是字符串我是字符串",3,4);//符串我是
        //4.释放资源
        fw.close();
    }
}

字符输出流的续写和换行

  • FileWriter(File file, boolean append)
    根据给定的 File 对象构造一个 FileWriter 对象。
  • FileWriter(String fileName, boolean append)
    根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象。

File file和String fileName->表示写入数据的目的地

boolean appebd表示续写开关:true->不会创建新的文件覆盖,支持续写 false->创建新的文件覆盖

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

/*
void write(char[] cbuf)
          写入字符数组。
abstract  void write(char[] cbuf, int off, int len)
          写入字符数组的某一部分。
 void write(int c)
          写入单个字符。
 void write(String str)
          写入字符串。
 void write(String str, int off, int len)
          写入字符串的某一部分。

 */
public class DemosFile13 {
    public static void main(String[] args) throws IOException {
        //1.创建一个FileWriter对象,构造方法中绑定要读取的数据源
        FileWriter fw = new FileWriter("FileAndIO\\src\\main\\java\\abc.txt\\e.txt",true);
        for (int i = 0; i < 10; i++) {
            fw.write("\r\n");//每次写入数据并换行
            fw.write("字符输出流的续写与换行");
        }
        fw.close();
    }
}

IO异常的处理

在JDK1.7之前:

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

/*
在jdk1.7之前使用try catch finally 处理流中的异常
格式:

    try{
        可能会产生异常的代码
    }catch(异常类变量 变量名){
        异常的处理逻辑
    }finally{
        一定会执行的代码
        资源释放
    }

 */
public class DemosFile13 {
    public static void main(String[] args){
        //扩大fw的作用域,让finally可以使用fw
        //变量在定义的时候可以没有值,但是再使用的时候必须有值
        //fw = new FileWriter("FileAndIO\\src\\main\\java\\abc.txt\\e.txt",true);这行代码如果执行失败,fw就会没有值,fw.close();就会报错
        FileWriter fw = null;
        //1.创建一个FileWriter对象,构造方法中绑定要读取的数据源
        try {
            fw = new FileWriter("WileAndIO\\src\\main\\java\\abc.txt\\e.txt",true);//故意写个错误路径
            for (int i = 0; i < 10; i++) {
                fw.write("\r\n");//每次写入数据并换行
                fw.write("字符输出流的续写与换行");
            }
        }catch (IOException e){
            System.out.println(e);
        }finally {
            //创建fw对象失败了,fw的值还是null,而null是不能调用方法的,所以fw.close();会抛出空指针异常
            //所以需要增加一个判断,不是null再把资源释放
            if (fw!=null){
                try {
                    //fw.close();发发声明抛出了IOException异常对象,所以我们必须处理这个异常对象,要么throw要么try catch
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }
}

JDK7的新特性

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

/*
在JDK7的新特性
在try的后边可以增加一个(),在括号中可以定义流对象
那么这个流对象的作用域就在try中有效
try中的代码执行完毕会自动把流对象释放,不用写finally
格式:

    try(定义流对象;定义流对象;...){
        可能会产生异常的代码
    }catch(异常类变量 变量名){
        异常的处理逻辑
    }
 */
public class DemosFile13 {
    public static void main(String[] args){
        try(FileWriter fw = new FileWriter("WileAndIO\\src\\main\\java\\abc.txt\\e.txt",true)/*故意写个错误路径*/){
            for (int i = 0; i < 10; i++) {
                fw.write("\r\n");//每次写入数据并换行
                fw.write("字符输出流的续写与换行");
            }
        }catch (IOException e){
            System.out.println(e);
        }
    }
}

JDK9的新特性

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

/*
在JDK9的新特性
在try的前边可以定义一个流对象,在try的后面的()中可以直接引入流对象的名称(变量名)
try中的代码执行完毕会自动把流对象释放,不用写finally不用写fw.close
格式:
    A a = new A();
    B b = new B();
    try(a,b){
        可能会产生异常的代码
    }catch(异常类变量 变量名){
        异常的处理逻辑
    }
 */
public class DemosFile13 {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("FileAndIO\\src\\main\\java\\abc.txt\\e.txt",true);
        try(fw){
            for (int i = 0; i < 10; i++) {
                fw.write("\r\n");//每次写入数据并换行
                fw.write("字符输出流的续写与换行");
            }
        }catch (IOException e){
            System.out.println(e);
        }
    }
}

posted @ 2021-05-04 11:41  牛牛ō^ō  阅读(141)  评论(0编辑  收藏  举报