java学习笔记 - IO流操作汇总及自己实现复制文件案例

IO流

一.File类

想要input和output,用什么写到硬盘上呢?当然要先熟悉文件操作。

1.1 定义

java.io.File类:文件和文件目录路径的抽象表示形式,与平台无关
File 能新建、删除、重命名文件和目录,但 File 不能访问文件内容本身。
如果需要访问文件内容本身,则需要使用输入/输出流。
想要在Java程序中表示一个真实存在的文件或目录,那么必须有一个File对
象,但是Java程序中的一个File对象,可能没有一个真实存在的文件或目录。
File对象可以作为参数传递给流的构造器。

1.2 构造器

public File(String pathname):以pathname为路径创建File对象,可以是 绝对路径或者相对路径,如果pathname是相对路径,则默认的当前路径在系统属性user.dir中存储。
public File(String parent,String child)
public File(File parent,String child)

1.3 常用API

public String getAbsolutePath():获取绝对路径
public String getParent():获取上层文件目录路径。若无,返回null
public String[] list() :获取指定目录下的所有文件或者文件目录的名称数组
public File[] listFiles() :获取指定目录下的所有文件或者文件目录的File数组
public boolean isDirectory():判断是否是文件目录
public boolean isFile() :判断是否是文件
public boolean exists() :判断是否存在
public boolean createNewFile() :创建文件。若文件存在,则不创建,返回false
public boolean mkdir() :创建文件目录。如果此文件目录存在,就不创建了。如果此文件目录的上层目录不存在,也不创建。
public boolean mkdirs() :创建文件目录。如果上层文件目录不存在,一并创建

二.IO流

2.1 this is IO

I/O是Input/Output的缩写, I/O技术是非常实用的技术,用于处理设备之间的数据传输。如读/写文件,网络通讯等。
Java程序中,对于数据的输入/输出操作以 “流(stream)” ” 的方式进行。
java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过 标准的方法输入或输出数据。

2.2 IO流的两种基本分类

根据数据的流向分为:输入流和输出流。
输入流 :把数据从 其他设备 上读取到 内存 中的流。
输出流 :把数据从 内存 中写出到 其他设备 上的流。
格局数据的类型分为:字节流和字符流。
字节流 :以字节为单位,读写数据的流。
字符流 :以字符为单位,读写数据的流。

2.3 四个顶级父类

基本所有的流都得叫一声爸爸,记清楚了你就搞懂了基本的分类
输入输出,相较的是我们,即内存
在这里插入图片描述

2.4 字节流和字符流

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

字节输出流

java.io.OutputStream 抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地。它定义了字
节输出流的基本共性功能方法。
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) :将指定的字节输出流

字节输入流

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

字符输入、输出流

操作类似,不过每次读写的单位从byte数组变成了char数组,聪明的你应该可以类比过来,不再赘述
tips:亲记得使用完后释放内存哦

2.5 节点流和处理流

前面的字符和字节流,都是最基础的流,一般工作中,我们使用性能更快的处理流。何为处理流?流上加流,即为处理流。
在这里插入图片描述

2.6 最常用的处理流:缓冲流

为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组,缺省使用8192个字节(8Kb)的缓冲区。
缓冲流要“套接”在相应的节点流之上,根据数据操作单位可以把缓冲流分为:
BufferedInputStream 和 BufferedOutputStream
BufferedReader 和 BufferedWriter
看到这四个东西,有没有一丝丝的眼熟呢?^ ^
当使用BufferedInputStream读取字节文件时,BufferedInputStream会一次性从文件中读取8192个(8Kb),存在缓冲区中,直到缓冲区装满了,才重新从文件中读取下一个8192个字节数组。这就是他性能更高的小秘密。

2.7 处理流还有什么?

转换流:

实现将字符的输出流按指定字符集转换为字节的输出流。
需要和OutputStream“套接”。
构造器方法:
public OutputStreamWriter(OutputStream out)
public OutputSreamWriter(OutputStream out,String charsetName)

标准输入、输出流:

System.in和System.out分别代表了系统标准的输入和输出设备
默认输入设备是:键盘,输出设备是:显示器
System.in的类型是InputStream
System.out的类型是PrintStream,其是OutputStream的子类

三.案例实现

喜闻乐见,最爱的环节来了。
我们自定义一个需求。要求把指定文件夹内(包括所有子文件夹里的内容)内指定格式的文件复制到指定的地方。
你有思路了吗?

package advancedgrammer.iostream;

import java.io.*;

public class testcopy {
    public static void main(String[] args) {
        //test it here
    }

    public static void copyFile(String src,String dis) {
        //使用缓冲流实现文件复制操作
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            File old_f = new File(src);
            File new_f = new File(dis);

            FileInputStream fis = new FileInputStream(old_f);
            FileOutputStream fos = new FileOutputStream(new_f);
            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);

            byte[] buf = new byte[10];
            int len;
            while ((len = bis.read(buf)) != -1) {
                bos.write(buf, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (bis != null) {
            try {
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (bos != null) {
            try {
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void findAndCopy(String from, String to, String required_suffix) {
        //使用递归遍历判断是否为文件,如果是文件则判断后缀名,相同则执行复制操作
        File target = new File(to);
        if (!target.isDirectory()) {
            System.out.println("请输入文件夹名!");
            return;
        }

        File file = new File(from);
        if (file.isDirectory()) {
            File[] children = file.listFiles();
            for (File child : children) {
                String absolutePath = child.getAbsolutePath();
                findAndCopy(absolutePath, to, required_suffix);
            }
        } else {
            if (!target.exists()) {
                target.mkdirs();
            }
            String[] split = from.split("\\\\");
            String filename = split[split.length - 1];
            String[] period_split = filename.split("\\.");
            String suffix = period_split[period_split.length - 1];
            if (suffix.equals(suffix)){
                String toFullPath = to + filename;
                copyFile(from, toFullPath);
            }
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值