IO流详解之字符流与File类

IO流

1.字符流简介

  • 字符流核心组成
    • 核心组成:Reader--> 字符输入流、Writer--> 字符输出流、BufferedReader-->字符缓冲流读取文件、BufferedWriterr-->字符缓冲流文写入件

  • 字符流

    • 字节流能操作所有文件,而字符流操作文本文件比较方便
    • 解决了乱码问题
  • 字节流与字符流的区别:

    • 在所有的流操作里。字节永远是最基础的。任何基于字节的操作都是正确的

    • 无论你是文本文件还是二进制的文件。如果确认流里面只有可打印的字符,包括英文的和各种国家的文字,也包括中文,那么可以考虑用字符流。由于编码不同,多字节的字符可能占用多个字节。比如GBK的汉字就占用2个字节,而UTF-8的汉字就占用3个字节。所以,字符流是根据指定的编码,将1个或多个字节转化为java里面的unicode的字符,然后进行操作

    • 字符操作一般使用Writer,Reader等

    • 字节操作一般都是InputStream,OutputStream以及各种包装类,比如BufferedlnputStream和BufferedOutputStream等。

    • 如果你确认你要处理的流是可打印的字符,那么使用字符流会看上去简单一点。如果不确认,那么用字节流总是不会错的。

    • 一般操作非文本文件时,使用字节流;操作文本文件时,建议使用字符流。

2.字符流抽象类常见方法

2.1字符流抽象类

  • reader:字符输入流

    • public int read(){}
    • public int read(char[] c){}
    • public int read(char[] b, int off, int len){}
  • Writer: 字符输出流

    • public void write(int n){}
    • public void write(String str){}
    • public void write(char[] c){}

2.2文件字符流

  • FileReader:

    • public int read(char[] c) // 从流中读取多个字符,将读到的内容存入 c 数组,返回实际读到的字符数;如果达到文件的尾部,则返回 -1
  • FileWriter:

    • public void write(String str) // 一次写多个字符,将所有字符写入输出流

2.21 使用字节流读取文本文件代码演示

package stream.demo02;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
// 传统字节流读取txt中文文本
/*
使用传统字节流读中文文本,会出现乱码问题。因为字节流读入文件内容时是按照一个字节一个字节来读。
而hello.txt 采用UTF-8 编码格式,一个汉字占三字节,一节流的读入方式将一个汉字拆分为三字字节,所以读入内容出现了乱码


*/

public class Demo01 {
    public static void main(String[] args) throws IOException {
        // 1. 创建FileInputStream对象
        FileInputStream fis = new FileInputStream("D:\\hello.txt");


        // 2. 读取
        int count=0;
        while ((count=fis.read())!=-1){
            System.out.print((char)count);
        }//å¥½å¥½å­¦ä¹ ï¼Œå¤©å¤©å‘ä¸   乱码
        // 3. 关闭
        fis.close();
    }
}



运行结果

好好学习,天天向ä¸


2.22 使用文件字符流读取文件代码演示

package stream.demo02;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
//使用filereader读取文件
public class FileReaderTest {
    public static void main(String[] args) throws IOException {
        // 1. 创建FileReader 文件字符输入流
        FileReader frd = new FileReader("D:\\hello.txt");
        /*
        // 2. 读取
        // 2.1 单个字符读取
        int date=0;
        while ((date=frd.read())!=-1){//读取一个字符
            System.out.print((char)date);
        }
       */

        //读取多个字符

        char[] bytes = new char[5];// 字符缓冲区读取
        int count=0;
        while ((count=frd.read(bytes))!=-1){
            System.out.println(new String(bytes,0,count));
        }
        // 3. 关闭
       frd.close();

    }
}




运行结果

好好学习,
天天向上

2.23 使用文件字符流写入文件代码演示

package stream.demo02;

import java.io.FileWriter;
import java.io.IOException;
//使用filewriter 写入文件
public class FileWriteTest {
    public static void main(String[] args) throws IOException {
        // 1. 创建FileWriter对象
        FileWriter fileWriter = new FileWriter("D:\\write.txt");
        // 2. 写入
        for (int i = 0; i < 10; i++) {
            fileWriter.write("要精通java\r\n");

            fileWriter.flush();

        }
        System.out.println("执行完毕");
        // 3. 关闭
        fileWriter.close();

    }
}




运行结果

执行完毕

截图


2.24 利用字符流复制文件代码演示

package stream.demo02;

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

/*

   使用字节流可以复制任意文件
   使用FileReader和FileWriter复制文本文件,不能复制图片或二进制文件

   一切类型文件都是以二进制010101的形式存储在硬盘上,字符流读取文件时是按照编码格式例如UTF-8 读取,而图片音频等文件没有编码格式,因此字符流读入乱码

*/


public class FileCopyTest {
    public static void main(String[] args) throws IOException {
        // 1. 创建 FileReader   FileWriter
        FileReader frd = new FileReader("D:\\write.txt");
        FileWriter fwt = new FileWriter("D:\\write2.txt");

        // 2. 读写
        int count=0;
        while ((count=frd.read())!=-1){
            fwt.write(count);
            fwt.flush();

        }
        frd.close();
        fwt.close();
        System.out.println("执行完毕");
    }
}



运行结果

执行完毕

fuzhi

2.3 字符缓冲流

  • 缓冲流:BufferedReader / BufferedWriter
    • 高效读写
    • 支持输入换行符
    • 可一次写一行读一行


2.31 字符缓冲输入流代码演示:

package stream.demo02;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
//使用字符缓冲流读取文件
public class BufferReaderTest {
    public static void main(String[] args) throws IOException {
        // 创建缓冲流
        FileReader flr = new FileReader("D:\\write.txt");
        BufferedReader bufferedReader = new BufferedReader(flr);
        /*
        // 读取
        // 1. 第一种方式

        char[] chars=new char[1024];
        int count=0;
        while ((count=bufferedReader.read(chars))!=-1){
            System.out.println(new String(chars,0,count));
        }
        */
        // 2. 第二种方式 一行一行读取
        String st=null;
        while ((st=bufferedReader.readLine())!=null){//readLine():一行一行读取文件,返回值为String类型当没有下一行时返回null
            System.out.println(st);
        }
         // 关闭
        bufferedReader.close();
        System.out.println("执行完毕");

    }

}


运行结果

要精通java
要精通java
要精通java
要精通java
要精通java
要精通java
要精通java
要精通java
要精通java
要精通java
执行完毕

2.32 字符缓冲输出流代码演示:

package stream.demo02;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
//使用字符缓冲流写入文件
public class BufferWriterTest {
    public static void main(String[] args) throws IOException {
        // 1. 创建BufferedWriter对象
        FileWriter fileWriter = new FileWriter("D:\\buffer.txt");
        BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
        // 2. 写入
        for (int i = 0; i < 10; i++) {
            bufferedWriter.write("我爱学习,学习爱我");
            bufferedWriter.newLine(); // 写入一个换行符  相当于windows \r\n  linux  \n
            bufferedWriter.flush();
        }
        // 3. 关闭
        bufferedWriter.close();// 此时会自动关闭fw
        System.out.println("执行完毕");

    }
}


运行结果

执行完毕

ddd


2.4 打印流

  • PrintWriter

    • 封装了 print() / println()方法,支持写入后换行
    • 支持数据原样打印

2.41 打印流代码演示:

package stream.demo02;

import java.io.FileNotFoundException;
import java.io.PrintWriter;

//功能:将数据打印到文件里    数据在代码里什么样子,打印出来就是什么样子
public class PrintWriterTest {
    public static void main(String[] args) throws FileNotFoundException {
        // 1 创建打印流
        PrintWriter printWriter = new PrintWriter("D:\\print.txt");

        // 2 打印
        printWriter.println(65);
        printWriter.println(true);
        printWriter.println(3.1415);
        printWriter.print("A");
        // 3 关闭
        printWriter.close();
        System.out.println("打印完毕");

    }
}


运行结果

打印完毕


ttt


2.5 转换流

  • 桥转换流:InputStreamReader / OutputStreamWriter

    • 可将字节流转换为字符流
    • 可设置字符的编码方式

2.51 转换流读文件代码演示:

package stream.demo03;

import java.io.*;

//使用inputStreamReader 读取文件,指定使用的编码  (和FileinputStream 最大区别就是可以指定编码)
public class InputStreamReaderTest {
    public static void main(String[] args) throws IOException {
        // 1 创建InputStreamReader对象
        FileInputStream fis  = new FileInputStream("D:\\write.txt");
        InputStreamReader inputStreamReader = new InputStreamReader(fis,"utf-8");
        // 2 读取文件
        int count=0;
        while ((count=inputStreamReader.read())!=-1){
            System.out.print((char)count);
        }
        // 3 关闭
        inputStreamReader.close();
        System.out.println("执行完毕");


    }
}

运行结果

要精通java
要精通java
要精通java
要精通java
要精通java
要精通java
要精通java
要精通java
要精通java
要精通java
执行完毕


2.52 转换流写文件代码演示:

package stream.demo03;

import java.io.*;
//转换流 使用OutputStreamWriter 写文件  使用指定的编码
public class OutputStreamWriterTest {
    public static void main(String[] args) throws IOException {
        // 1 创建OutputStreamReader对象
        FileOutputStream fos = new FileOutputStream("D:\\utf.txt");
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fos,"utf-8");
        // 2 写入
        for (int i = 0; i < 10; i++) {
            outputStreamWriter.write("我爱中国,热爱祖国\n\r");// **\r:**回车,移动到当前行行首;
                                                      //**\n:**换行,换到当前位置的下一行,但是不会回到行首;
                                                      //**\r\n:**回车+换行,移动到下一行的行首
            outputStreamWriter.flush();

        }
        // 3 关闭
        outputStreamWriter.close();
        System.out.println("执行完毕");

    }
}

运行结果

执行完毕

uuu


3.File 类

  • 概念:代表物理盘符中的一个文件或者文件夹
    • IO 流: 对文件的内容操作.

    • File 类: 对文件自身进行操作,eg:删除文件,文件重新命名等.

3.1 常用方法

  • 目前常见的方法有:
    • createNewFile()// 创建一个新文件
    • mkdir() //创建文件夹
    • delete() // 删除文件或空文件夹
    • exists() // 判断 File 对象所代表的对象是否存在
    • getAbsolutePath() // 获取文件的绝对路径
    • getName() // 获取名字
    • getParent() // 获取 文件/目录 所在的目录
    • isDirectory() // 是否是目录,而不是文件
    • isFile() 是否为文件,而不是目录
    • length() // 获取文件的长度
    • listFiles() // 列出目录中所有内容
    • renameTo() // 更改文件的名字

3.1 文件操作代码演示:

package stream.demo04;

import java.io.File;
import java.io.IOException;
import java.util.Date;
/*
File类的使用
1. 分隔符
2. 文件操作
3. 文件夹操作
*/
//对文件进行操作
public class FileTest {
    public static void main(String[] args) throws Exception {
        sepearatorTest();
        fileOpTest();
    }
    // 1. 分隔符
    public static void sepearatorTest(){
        System.out.println("打印路径分割符:"+File.pathSeparator);
        System.out.println("名称分割符:"+File.separator);
    }
    // 2. 文件操作
    public static void fileOpTest() throws IOException, InterruptedException {
        // 1. 创建文件
        File file = new File("D:\\file.txt");
        if(!file.exists()){// 是否存在
        boolean newFile = file.createNewFile();
        System.out.println("创建结果:"+newFile);
        }
        // 2. 删除文件两个删除方法
        // 2.1 直接删除
        //System.out.println("删除结果:"+file.delete());


        // 2.2 使用jvm退出时删除
//        file.deleteOnExit();
//        Thread.sleep(5000);

        // 3. 获取文件信息
        System.out.println("获取文件绝对路径"+file.getAbsolutePath());
        System.out.println("获取文件相对路径"+file.getPath());
        System.out.println("获取文件名称"+file.getName());
        System.out.println("获取文件父目录"+file.getParent());
        System.out.println("获取文件的长度"+file.length());
        System.out.println("获取文件的创建时间"+new Date(file.lastModified()).toLocaleString());

        // 4. 判断
        System.out.println("是否是文件:"+file.isFile());
        System.out.println("是否可写:"+file.canWrite());
        System.out.println("是否隐藏:"+file.isHidden());

    }



}


运行结果

打印路径分割符:;
名称分割符:\
获取文件绝对路径D:\file.txt
获取文件相对路径D:\file.txt
获取文件名称file.txt
获取文件父目录D:\
获取文件的长度27
获取文件的创建时间2022-7-7 16:31:48
是否是文件:true
是否可写:true
是否隐藏:false


3.2 文件夹操作代码演示:

package stream.demo04;

import java.io.File;
import java.io.FileFilter;
import java.util.Date;
//文件夹操作
public class DirOpeTest {
    public static void main(String[] args) throws InterruptedException {

        dirTest();

    }
    public static void dirTest() throws InterruptedException {
        // 1. 创建文件夹
        File dir = new File("D:\\aa\\bb\\cc");
        if(!dir.exists()){
            //dir.mkdir(); // 只能创建单级目录
            System.out.println("创建文件夹结果"+dir.mkdirs());// 创建多级目录
        }

        // 2. 删除文件夹
        // 2.1 直接删除
        //dir.delete();// 只能删除最底层空目录
        // 2.2 使用jvm删除
       // dir.deleteOnExit();
        //Thread.sleep(5000);

        // 3. 获取文件夹信息
        System.out.println("获取文件夹绝对路径:"+dir.getAbsolutePath());
        System.out.println("获取文件夹路径:"+dir.getPath());
        System.out.println("获取父目录:"+dir.getParent());
        System.out.println("获取最后一次调整时间:"+new Date(dir.lastModified()).toLocaleString());
        System.out.println("获取文件夹名称:"+dir.getName());

        // 4. 判断
        System.out.println("判断文件夹是否存在:"+dir.exists());
        System.out.println("是否隐藏:"+dir.isHidden());

        // 5. 遍历文件夹  使用list()
        File dir2 = new File("D:\\aa");
        String[] list = dir2.list();
        System.out.println("=======================");
        for (String s : list) {
            System.out.println(s);
        }

        System.out.println("------------FileFilter的使用-------------------");

        //使用listFiles() 遍历文件夹
        File[] files = dir2.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                if(pathname.getName().endsWith("jpg")){
                    return true;
                }
                return false;
            }
        });

        for (File file : files) {
            System.out.println(file.getName());
        }


    }

}

运行结果

获取文件夹绝对路径:D:\aa\bb\cc
获取文件夹路径:D:\aa\bb\cc
获取父目录:D:\aa\bb
获取最后一次调整时间:2022-7-12 20:39:30
获取文件夹名称:cc
判断文件夹是否存在:true
是否隐藏:false
=======================
13-1F113092322-50.jpg
13-1F1130Z915.jpg
bb
------------FileFilter的使用-------------------
13-1F113092322-50.jpg
13-1F1130Z915.jpg


3.3 文件夹遍历操作代码演示:

package stream.demo04;

import java.io.File;
//文件夹遍历操作
public class ListdirDemo {
    public static void main(String[] args) {

        listDir(new File("D:\\aa"));
        deleteDir(new File("D:\\aa"));

    }
        //递归遍历文件夹所有文件
    public static void listDir(File dir){

        File[] files = dir.listFiles();//获取文件夹中所有文件

        System.out.println(dir.getAbsolutePath());

        if(files!=null&&files.length>0){
            for (File file : files) {//遍历files 文件夹中所有内容
                 if (file.isDirectory()){//若该内容是一个文件夹,则递归调用listDIr()方法,进入该文件夹然后重复判断文件夹是否还有文件夹
                     listDir(file);
                 }else {
                     System.out.println(file.getAbsolutePath()//直到递归内容不是文件夹为止,打印当前文件内容的绝对路径
                     );

                 }

            }
        }

    }

    //递归 删除文件夹及所有文件
    public static void deleteDir(File dir){
        File[] files = dir.listFiles();
        if(files!=null&&files.length>0){
            for (File file : files) {
                if (file.isDirectory()){//files中有子文件夹和文件,判断当前内容是否是文件,是文件递归调用方法,进入子文件夹
                    deleteDir(file);//递归
                }else {
                    //删除文件
                    System.out.println(file.getAbsolutePath()+"删除文件:"+file.delete());
                }
            }

        }
        System.out.println(dir.getAbsolutePath()+"删除:"+dir.delete());//当该文件夹中内容删除完毕时,删除文件夹
    }



}

运行结果

D:\aa
D:\aa\13-1F113092322-50.jpg
D:\aa\13-1F1130Z915.jpg
D:\aa\bb
D:\aa\bb\cc
D:\aa\bb\fjogan.jfif
D:\aa\bb\girl_cloth1.jpg
D:\aa\bb\girl_cloth2.jpg
D:\aa\bb\i1636011671_2947_0.jpg
D:\aa\bb\idCard1.png
D:\aa\bb\increment.meta
D:\aa\13-1F113092322-50.jpg删除文件:true
D:\aa\13-1F1130Z915.jpg删除文件:true
D:\aa\bb\cc删除:true
D:\aa\bb\fjogan.jfif删除文件:true
D:\aa\bb\girl_cloth1.jpg删除文件:true
D:\aa\bb\girl_cloth2.jpg删除文件:true
D:\aa\bb\i1636011671_2947_0.jpg删除文件:true
D:\aa\bb\idCard1.png删除文件:true
D:\aa\bb\increment.meta删除文件:true
D:\aa\bb删除:true
D:\aa删除:true


————————————————————————————————————————————————————————————————————————————

更多参考

千峰教育-IO框架

posted @ 2022-07-12 20:46  哼哼哈¥  阅读(347)  评论(0编辑  收藏  举报