Java IO

目录

File类

常见用法

遍历目录文件

遍历指定目录下所有文件

遍历指定目录下指定扩展名的文件

遍历包括子目录下的文件在内的所有文件

删除文件及目录

字节流

读文件

写文件

文件复制

字符流

读文件

写文件

转换流


I:Input 输入       将文件内容以数据流的方式读入内存

O:Output 输出  将内存数据写入文件

File类

File类是唯一一个表示磁盘文件的对象。提供了各种方法,可以实现创建,删除,重命名文件等等。

常见用法

package Example1;

import java.io.File;

public class Test1 {
    public static void main(String[] args) {
        // 创建文件对象
        File f = new File("src/test1.txt");
        
        // 测试File类常用方法
        System.out.println("文件是否存在:"+f.exists());
        System.out.println("文件名:" + f.getName());
        System.out.println("文件大小:" + f.length() + " bytes");
        System.out.println("文件相对路径:"+f.getPath());
        System.out.println("文件绝对路径:"+f.getAbsolutePath());
        System.out.println("文件删除是否成功:"+f.delete());
    }
}

遍历目录文件

获取目录下所有文件和目录名称。

遍历指定目录下所有文件

package Example2;

import java.io.File;

public class Test2 {
    public static void main(String[] args) {
        File f = new File("src/TestDir");
        if (f.isDirectory()) {
            String[] names = f.list();
            for(String name:names) {
                System.out.println(name);
            }
        }
    }
}

遍历指定目录下指定扩展名的文件

package Example3;

import java.io.File;
import java.io.FilenameFilter;

public class Test3 {
    public static void main(String[] args) {
        File f = new File("src/TestDir");

        // 创建文件过滤器对象 FilenameFilter是一个接口
        FilenameFilter ff = new FilenameFilter() {
            // 重写accept()方法
            @Override
            public boolean accept(File dir, String name) {
                File currFile = new File(dir,name);
                if(currFile.isFile() && name.endsWith(".txt")) {
                    return true;
                } else {
                    return false;
                }
            }
        };
        if (f.exists()) {
            // list()方法接收一个 FilenameFilter类型参数 ,它是一个文件过滤器,accept()方法对指定目录进行迭代
            String[] lists = f.list(ff);
            for(String name:lists) {
                System.out.println(name);
            }
        }
    }
}

遍历包括子目录下的文件在内的所有文件

package Example4;

import java.io.File;

public class Test4 {
    public static void main(String[] args) {
        File f = new File("src/TestDir");
        fileDir(f);
    }

    public static void fileDir(File dir) {
        File[] files = dir.listFiles(); // listFiles() 获得表示目录下所有文件的数组
        for(File file:files) { // 遍历所有的文件
            if (file.isDirectory()) { // 如果是文件夹就递归调用
                fileDir(file);
            }
            System.out.println(file.getAbsolutePath());
        }
    }
}

删除文件及目录

delete()只能删除空白目录,不能删除目录下有文件的目录

package Example5;

import java.io.File;

public class Test5 {
    public static void main(String[] args) {
        File f = new File("src/TestDir");
        deleteDir(f);
        System.out.println("删除成功!");
    }

    public static void deleteDir(File dir) {
        if(dir.exists()) {
            File[] files = dir.listFiles(); 
            for(File file:files) {
                if(file.isDirectory()) {
                    deleteDir(file);
                } else {
                    file.delete();
                }
            }
            dir.delete();
        }
    }
}

字节流

在计算机上,所有的文件都是以二进制(字节)形式存在的。字节流是程序中最常用的流,根据数据的传输方向可以分为字节输入流和字节输出流。

JDK提供了两个抽象类:InputStream和OutputStream,是字节流得顶级父类,所有得类都继承自他们两个。他们两个可以理解为管道,连接文件和程序(内存)

读文件

package Example6;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

public class Test6 {
    public static void main(String[] args) throws Exception {
        InputStream input=null;
        // 可能读文件时会出现I/O错误,使用try...finally 保证IO流得关闭
        try{
            // 创建字节流对象
            FileInputStream in = new FileInputStream("src/TestDir/Test1.txt");
            // 用b记录每次读取得1字节,存储得是ASCII码值
            int b = 0;
            while(true) {
                b=in.read();
                if(b==-1){
                    break;
                }
                System.out.println(b);
                // in.close();
            }
        } finally {
            if(input!=null){
                input.close();
            }
        }
    }
}

写文件

package Example6;

import java.io.FileOutputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;

public class Test7 {
    public static void main(String[] args) throws Exception{
        OutputStream ouput = null;
        try{
            // OutputStream os = new FileOutputStream("src/TestDir/Test1.txt",true); 会覆盖文件原来得内容
            OutputStream os = new FileOutputStream("src/TestDir/Test1.txt",true); // 文件后面追加内容
            String str = "欢迎你!";
            byte[] b = str.getBytes();
            for(int i=0;i<b.length;i++) {
                os.write(b[i]);
            }
            // os.close();
        } finally {
            if(ouput!=null){
                ouput.close();
            }
        }
    }
}

文件复制

package Example6;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

public class Test8 {
    public static void main(String[] args) throws Exception {
        // 创建输入流,读取a.png文件
        InputStream in = new FileInputStream("src/TestDir/a.jpg");
        // 创建输出流,将读取得数据写入b.png下
        OutputStream os = new FileOutputStream("src/TestDir/b.jpg");

        int len;

        // 获取复制之前时间
        long t1 = System.currentTimeMillis();

        while((len=in.read())!=-1) {
            os.write(len);
        }

        // 获取复制之后时间
        long t2 = System.currentTimeMillis();
        System.out.println("复制消耗得时间" + (t2 - t1 + "ms"));

        in.close();
        os.close();
    }
}

为了提高效率,可以设置一个字节数组作为缓冲区,复制时一次性读取多个字节数据保存在数组中,再将数组一次性写入文件,减少了对文件得操作次数,提升效率。

package Example6;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

public class Test9 {
    public static void main(String[] args) throws Exception {
        // 创建输入流,读取a.png文件
        InputStream in = new FileInputStream("src/TestDir/a.jpg");

        // 创建输出流,将读取得数据写入c.png下
        OutputStream os = new FileOutputStream("src/TestDir/c.jpg");

        // 缓冲区读写文件
        byte[] buff =new byte[1024];
        int len;
        long t1 = System.currentTimeMillis();

        // len 记录读入缓冲区得字节数
        while((len=in.read(buff))!=-1){
            os.write(buff,0,len);
        }

        long t2 = System.currentTimeMillis();
        System.out.println("复制消耗得时间" + (t2 - t1 + "ms"));

        in.close();
        os.close();
    }
}

字符流

如果读写文件得内容是字符,考虑到字节流读写字符可能存在传输效率和字符编码问题,建议使用字符流。

JDK中提供了两个抽象顶级父类Reader和Writer。

读文件

package Example7;

import java.io.FileReader;

public class Test7 {
    public static void main(String[] args) throws Exception {
        // 创建一个FileReader对象,用来读取文件中得字符
        FileReader r = new FileReader("src/TestDir/Test1.txt");
        int ch;
        while((ch=r.read())!=-1) {
            System.out.print((char)ch);
        }
        r.close();
    }
}

写文件

package Example7;

import java.io.FileWriter;

public class Test8 {
    public static void main(String[] args) throws Exception{
        // 创建字符流对象,向文件写数据 不加true表示覆盖
        FileWriter fw = new FileWriter("Test1.txt",true);
        String str = "静心得意";
        fw.write(str);
        fw.write("\r\n"); //换行输出 '\r'是回车,'\n'是换行,前者使光标到行首,后者使光标下移一格。
        fw.write(str);
        fw.close();
    }
}

转换流

转换流可以把字节流和字符流相互转换

JDK提供了InputStreamReader和OutputStreamWriter,InputStreamReader和OutputStreamWriter可以方便读取,写入字符,提升效率。

package Example8;

import java.io.*;

public class Test8 {
    public static void main(String[] args) throws Exception{
        // 创建字节输入流,并指定文件
        FileInputStream fis = new FileInputStream("src/TestDir/Test1.txt");
        // 将字节流转换为字符流
        InputStreamReader isr = new InputStreamReader(fis);
        // 创建字节输出流
        FileOutputStream fos = new FileOutputStream("src/TestDir/Test2.txt");
        // 将字节流转换为字符流
        OutputStreamWriter osw = new OutputStreamWriter(fos);
        
        int ch;

        while((ch=isr.read())!=-1){
            osw.write(ch);
        }

        isr.close();
        osw.close();
    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dao-道法自然

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值