震惊!居然还有人用cv方式复制粘贴文件!快来看看IO流怎么实现叭!

前言

在这个动不动就让你cmd,让你%temp%的时代里面,你还在用你的鼠标和cv吗?还要一个一个的去打开文件夹,cv文件吗?你low爆了,来看看不一样的我们咋搞得。

搞事情

文件的传输

  在我们得认知中,有多少和以前得我一样,觉得cv嗯真香,没有什么cv不了得,可是有没有想过cv鼠标难得点,尤其是,笔记本没有鼠标,用触摸板得我,很难受鸭!
  那么我们今天一起看看没有鼠标得cv文件叭。

File类

一、 File类的定义

  ① File类主要是Java为文件这一块的操作(删除,复制,粘贴,新增)而设计的相关类。
  ② File类的包名是java.io,用的时候需要导包,它实现了Serializable,Comparable两大接口便于可序列化和比较。

概述
它是文件和目录路径名的抽象表示
文件和目录是可以通过File封装成对象的
对于File而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已。它可以是存在的,也可以是不存在的。将来是要通过具体的操作把这个路径的内容转换为具体存在的

底层源码定义

public class File implements Serializable, Comparable<File>
{
    
    
}

二、File类的构造方法(常用)

1、File类的使用

方法名 说明 实例
File(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例 File f1 = new File("E:\\pier\\java.txt"); System.out.println(f1);
File(String parent, String child) 从父路径名字符串和子路径名字符串创建新的 File实例 File f2 = new File("E:\\pier","java.txt");System.out.println(f2);
File(File parent, String child) 从父抽象路径名和子路径名字符串创建新的 File实例 File f3 = new File("E:\\pier");File f4 = new File(f3,"java.txt");System.out.println(f4);

上面表格中的实例不太好看,可以看看下面的代码,因为在表格中换行不太行,就直接连在一起的格式不好看。

public class FileDemo01 {
    
    
    public static void main(String[] args) {
    
    
        //File(String pathname):通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
        File f1 = new File("E:\\pier\\java.txt");
        System.out.println(f1);

        //File(String parent, String child):从父路径名字符串和子路径名字符串创建新的 File实例。
        File f2 = new File("E:\\pier","java.txt");
        System.out.println(f2);

        //File(File parent, String child):从父抽象路径名和子路径名字符串创建新的 File实例。
        File f3 = new File("E:\\pier");
        File f4 = new File(f3,"java.txt");
        System.out.println(f4);
    }
}

注意输出的是你的 File路径,不确定你的路径是否拥有。
结果

E:\pier\java.txt
E:\pier\java.txt
E:\pier\java.txt

2、File类的创建和使用

这里由于上面的表格的教训我就不在后面写实例了,需要实例的自己去看后面的带代码

创建文件

方法 说明
public boolean createNewFile() 当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件
public boolean mkdir() 创建由此抽象路径名命名的目录
public boolean mkdirs() 创建由此抽象路径名命名的目录
public boolean mkdirs() 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录

创建文件代码实例

注:如果有人想要偷懒只想要一根斜线的话,可以使用 /
使用两根\的主要目的是为了防止出现和\n这类符号出现歧义的情况所采取的

 public static void main(String[] args) throws IOException {
    
    
        //需求1:我要在E:\\pier目录下创建一个文件java.txt
        File f1 = new File("E:\\pier\\java.txt");
        System.out.println(f1.createNewFile());
        System.out.println("--------");

        //需求2:我要在E:\\pier目录下创建一个目录JavaSE
        File f2 = new File("E:\\pier\\JavaSE");
        System.out.println(f2.mkdir());
        System.out.println("--------");

        //需求3:我要在E:\\pier目录下创建一个多级目录JavaWEB\\HTML
        File f3 = new File("E:\\pier\\JavaWEB\\HTML");
//        System.out.println(f3.mkdir());
        System.out.println(f3.mkdirs());
        System.out.println("--------");

        //需求4:我要在E:\\pier目录下创建一个文件javase.txt
        File f4 = new File("E:\\pier\\javase.txt");
//        System.out.println(f4.mkdir());
        System.out.println(f4.createNewFile());
    }

判断功能

方法 说明
public boolean isDirectory() 测试此抽象路径名表示的File是否为目录
public boolean isFile() 测试此抽象路径名表示的File是否为文件
public boolean exists() 测试此抽象路径名表示的File是否存在

获取功能

方法 说明
public String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串
public String getPath() 将此抽象路径名转换为路径名字符串
public String getName() 返回由此抽象路径名表示的文件或目录的名称
public String[] list() 返回此抽象路径名表示的目录中的文件和目录的名称字符串数组
public File[] listFiles() 返回此抽象路径名表示的目录中的文件和目录的File对象数组

判断和获取代码实例

public static void main(String[] args) {
    
    
        //创建一个File对象
        File f = new File("myFile\\java.txt");

//        public boolean isDirectory():测试此抽象路径名表示的File是否为目录
//        public boolean isFile():测试此抽象路径名表示的File是否为文件
//        public boolean exists():测试此抽象路径名表示的File是否存在
        System.out.println(f.isDirectory());
        System.out.println(f.isFile());
        System.out.println(f.exists());

//        public String getAbsolutePath():返回此抽象路径名的绝对路径名字符串
//        public String getPath():将此抽象路径名转换为路径名字符串
//        public String getName():返回由此抽象路径名表示的文件或目录的名称
        System.out.println(f.getAbsolutePath());
        System.out.println(f.getPath());
        System.out.println(f.getName());
        System.out.println("--------");

//        public String[] list():返回此抽象路径名表示的目录中的文件和目录的名称字符串数组
//        public File[] listFiles():返回此抽象路径名表示的目录中的文件和目录的File对象数组
        File f2 = new File("E:\\pier");

        String[] strArray = f2.list();
        for(String str : strArray) {
    
    
            System.out.println(str);
        }
        System.out.println("--------");

        File[] fileArray = f2.listFiles();
        for(File file : fileArray) {
    
    
//            System.out.println(file);
//            System.out.println(file.getName());
            if(file.isFile()) {
    
    
                System.out.println(file.getName());
            }
        }
    }

删除

public static void main(String[] args) throws IOException {
    
    
//        File f1 = new File("E:\\pier\\java.txt");
        //需求1:在当前模块目录下创建java.txt文件
        File f1 = new File("myFile\\java.txt");
//        System.out.println(f1.createNewFile());

        //需求2:删除当前模块目录下的java.txt文件
        System.out.println(f1.delete());
        System.out.println("--------");

        //需求3:在当前模块目录下创建pier目录
        File f2 = new File("myFile\\pier");
//        System.out.println(f2.mkdir());

        //需求4:删除当前模块目录下的pier目录
        System.out.println(f2.delete());
        System.out.println("--------");

        //需求5:在当前模块下创建一个目录pier,然后在该目录下创建一个文件java.txt
        File f3 = new File("myFile\\pier");
//        System.out.println(f3.mkdir());
        File f4 = new File("myFile\\pier\\java.txt");
//        System.out.println(f4.createNewFile());

        //需求6:删除当前模块下的目录pier
        System.out.println(f4.delete());
        System.out.println(f3.delete());
    }

I/O流

曾几何时,我们就听过IO流的大名,在各种各样的语言中听闻这个词,俗话说恋恋不忘,必有回响。今天它来了,下面我们嗯看一张图,来使用三遍读书法一探究竟这个所谓的IO流。
IO菜鸟

上图小结:不管是字符流和字节流,我们都差不多分为Input和Out两种,对应的就是输入输出流嘛,我们对于文件的操作大嘎子也就是这几种方式,一种对文件的读取,一种就是对文件的写入。
首先我们再来看一看什么叫做IO流,百度给的定义:流是一种抽象概念,它代表了数据的无结构化传递。按照流的方式进行输入输出,数据被当成无结构的字节序或字符序列。从流中取得数据的操作称为提取操作,而向流中添加数据的操作称为插入操作。用来进行输入输出操作的流就称为IO流。换句话说,IO流就是以流的方式进行输入输出。
说白了不就是你和文件的的不解之谜不就是IO流吗?
Java之中的IO流不就是Java程序和操作系统之间的通信用的方法吗?

字节流

  • 字节流抽象基类

    • InputStream:这个抽象类是表示字节输入流的所有类的超类
    • OutputStream:这个抽象类是表示字节输出流的所有类的超类
    • 子类名特点:子类名称都是以其父类名作为子类名的后缀
  • 字节输出流

    • FileOutputStream(String name):创建文件输出流以指定的名称写入文件
  • 使用字节输出流写数据的步骤

    • 创建字节输出流对象(调用系统功能创建了文件,创建字节输出流对象,让字节输出流对象指向文件)
    • 调用字节输出流对象的写数据方法
    • 释放资源(关闭此文件输出流并释放与此流相关联的任何系统资源)
      示例代码
public static void main(String[] args) throws IOException {
    
    
        //创建字节输出流对象
        //FileOutputStream(String name):创建文件输出流以指定的名称写入文件
        FileOutputStream fos = new FileOutputStream("myByteStream\\fos.txt");
        /*
            做了三件事情:
                A:调用系统功能创建了文件
                B:创建了字节输出流对象
                C:让字节输出流对象指向创建好的文件
         */
        //void write(int b):将指定的字节写入此文件输出流
        fos.write(97);
        //最后都要释放资源(一定要记得释放资源)
        //void close():关闭此文件输出流并释放与此流相关联的任何系统资源。
        fos.close();
    }

字节流写数据的三种方式

方法名 说明
void write(int b) 将指定的字节写入此文件输出流 一次写一个字节数据
void write(byte[] b) 将 b.length字节从指定的字节数组写入此文件输出流 一次写一个字节数组数据
void write(byte[] b, int off, int len) 将 len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流 一次写一个字节数组的部分数据

代码实例

public static void main(String[] args) throws IOException {
    
    
        //FileOutputStream(String name):创建文件输出流以指定的名称写入文件
        FileOutputStream fos = new FileOutputStream("myByteStream\\fos.txt");

//       	  void write(int b):将指定的字节写入此文件输出流
//        fos.write(97);
//        fos.write(98);
//        fos.write(99);
//        fos.write(100);
//        fos.write(101);

//            void write(byte[] b):将 b.length字节从指定的字节数组写入此文件输出流
//        byte[] bys = {97, 98, 99, 100, 101};
        //byte[] getBytes():返回字符串对应的字节数组
        byte[] bys = "abcde".getBytes();
//        fos.write(bys);

        //void write(byte[] b, int off, int len):将 len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流
//        fos.write(bys,0,bys.length);
        fos.write(bys,1,3);

        //释放资源
        fos.close();
    }
  • 字节流写数据如何实现换行

    • windows:\r\n
    • linux:\n
    • mac:\r
  • 字节流写数据如何实现追加写入

    • public FileOutputStream(String name,boolean append)
    • 创建文件输出流以指定的名称写入文件。如果第二个参数为true ,则字节将写入文件的末尾而不是开头
      代码实例
 	public static void main(String[] args) throws IOException {
    
    
        //创建字节输出流对象
//        FileOutputStream fos = new FileOutputStream("myByteStream\\fos.txt");
        FileOutputStream fos = new FileOutputStream("myByteStream\\fos.txt",true);

        //写数据
        for (int i = 0; i < 10; i++) {
    
    
            fos.write("hello".getBytes());
            fos.write("\r\n".getBytes());
        }

        //释放资源
        fos.close();
    }

看完了写数据,小伙伴们有去尝试吗?我们写过数据怎么拿出来呢?

疑问
字节流读数据的两种方式
  ①一次一个字节数据
直接上代码

public static void main(String[] args) throws IOException {
    
    
        //创建字节输入流对象
        //FileInputStream(String name)
        FileInputStream fis = new FileInputStream("myByteStream\\fos.txt");

        int by;
        /*
            fis.read():读数据
            by=fis.read():把读取到的数据赋值给by
            by != -1:判断读取到的数据是否是-1
         */
        while ((by=fis.read())!=-1) {
    
    
            System.out.print((char)by);
        }

        //释放资源
        fis.close();
    }

  ①一次一个字节数组

public static void main(String[] args) throws IOException {
    
    
        //创建字节输入流对象
        FileInputStream fis = new FileInputStream("myByteStream\\fos.txt");

        /*
            hello\r\n
            world\r\n

            第一次:hello
            第二次:\r\nwor
            第三次:ld\r\nr

         */

        byte[] bys = new byte[1024]; //1024及其整数倍
        int len;
        while ((len=fis.read(bys))!=-1) {
    
    
            System.out.print(new String(bys,0,len));
        }

        //释放资源
        fis.close();
    }

字符流

为什么会出现字符流

  • 字符流的介绍

    由于字节流操作中文不是特别的方便,所以Java就提供字符流

    字符流 = 字节流 + 编码表

  • 中文的字节存储方式

    用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文,如何识别是中文的呢?

    汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数

这里提到了编码表,给大家放一个我整理的编码表详解在这里叭
编码表
字符串中的编码解码问题

方法名 说明
byte[] getBytes() 使用平台的默认字符集将该 String编码为一系列字节
byte[] getBytes(String charsetName) 使用指定的字符集将该 String编码为一系列字节
String(byte[] bytes) 使用平台的默认字符集解码指定的字节数组来创建字符串
String(byte[] bytes, String charsetName) 通过指定的字符集解码指定的字节数组来创建字符串

注意字符流的输入输出基本上差不多,但是细微的差距基本上都是在他们所传的参数差异,可以重点注意一下。这里就不写实例了,详情可以参考上面的字节流,基本上差不多。
构造方法

方法名 说明
InputStreamReader(InputStream in) 使用默认字符编码创建InputStreamReader对象
InputStreamReader(InputStream in,String chatset) 使用指定的字符编码创建InputStreamReader对象
OutputStreamWriter(OutputStream out) 使用默认字符编码创建OutputStreamWriter对象
OutputStreamWriter(OutputStream out,String charset) 使用指定的字符编码创建OutputStreamWriter对象

** 写数据的五种方法**

方法名 说明
void write(int c) 写一个字符
void write(char[] cbuf) 写入一个字符数组
void write(char[] cbuf, int off, int len) 写入字符数组的一部分
void write(String str) 写一个字符串
void write(String str, int off, int len) 写一个字符串的一部分

刷新和关闭

方法名 说明
flush() 刷新流,之后还可以继续写数据
close() 关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据

读取

方法名 说明
int read() 一次读一个字符数据
int read(char[] cbuf) 一次读一个字符数组数据

文件的复制

上面的字符流和字节流大体的都搞清楚了,那么我们怎么来复制文件呢?

复制文本文件,其实就把文本文件的内容从一个文件中读取出来(数据源),然后写入到另一个文件中(目的地)
字节流复制

public static void main(String[] args) throws IOException {
    
    
        //根据数据源创建字节输入流对象
        FileInputStream fis = new FileInputStream("E:\\pier\\酒家.txt");
        //根据目的地创建字节输出流对象
        FileOutputStream fos = new FileOutputStream("Test复制\\酒家.txt");
		//两种读取方式均可,但第二种按照字节读取更快
        /*//读写数据,复制文本文件(一次读取一个字节,一次写入一个字节)
        int by;
        while ((by=fis.read())!=-1) {
            fos.write(by);
        }*/
        //读写数据,复制文本文件(一次读取一个字节数组)
        byte[] bys = new byte[1024];
        int len;
        while ((len=fis.read(bys))!=-1) {
    
    
            fos.write(bys,0,len);
        }

        //释放资源
        fos.close();
        fis.close();
    }

文件复制
字符流复制文件

字符流复制Java文件有奇效哟

public static void main(String[] args) throws IOException {
    
    
        //根据数据源创建字符输入流对象
        FileReader fr = new FileReader("myCharStream\\ConversionStreamDemo.java");
        //根据目的地创建字符输出流对象
        FileWriter fw = new FileWriter("myCharStream\\Copy.java");

        //读写数据,复制文件
//        int ch;
//        while ((ch=fr.read())!=-1) {
    
    
//            fw.write(ch);
//        }

        char[] chs = new char[1024];
        int len;
        while ((len=fr.read(chs))!=-1) {
    
    
            fw.write(chs,0,len);
        }

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

缓冲流

缓冲流又分为两种
  ①字节缓冲流

  • BufferOutputStream:该类实现缓冲输出流。 通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用

  • BufferedInputStream:创建BufferedInputStream将创建一个内部缓冲区数组。 当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节

构造方法介绍

方法名 说明
BufferedOutputStream(OutputStream out) 创建字节缓冲输出流对象
BufferedInputStream(InputStream in) 创建字节缓冲输入流对象

代码示例

 public static void main(String[] args) throws IOException {
    
    
        //字节缓冲输出流:BufferedOutputStream(OutputStream out)
 
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myByteStream\\bos.txt"));
        //写数据
        bos.write("hello\r\n".getBytes());
        bos.write("world\r\n".getBytes());
        //释放资源
        bos.close();
    

        //字节缓冲输入流:BufferedInputStream(InputStream in)
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("myByteStream\\bos.txt"));

        //一次读取一个字节数据
//        int by;
//        while ((by=bis.read())!=-1) {
    
    
//            System.out.print((char)by);
//        }

        //一次读取一个字节数组数据
        byte[] bys = new byte[1024];
        int len;
        while ((len=bis.read(bys))!=-1) {
    
    
            System.out.print(new String(bys,0,len));
        }

        //释放资源
        bis.close();
    }

  ②字符缓冲流

  • BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区大小,或者可以接受默认大小。默认值足够大,可用于大多数用途

  • BufferedReader:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,可以指定缓冲区大小,或者可以使用默认大小。 默认值足够大,可用于大多数用途

字符缓冲流构造方法

方法名 说明
BufferedWriter(Writer out) 创建字符缓冲输出流对象
BufferedReader(Reader in) 创建字符缓冲输入流对象

字符缓冲流特有功能

代码实例

方法 方法名 说明
BufferedWriter void newLine() 写一行行分隔符,行分隔符字符串由系统属性定义
BufferedReader String readLine() 读一行文字。 结果包含行的内容的字符串,不包括任何行终止字符如果流的结尾已经到达,则为null
public static void main(String[] args) throws IOException {
    
    
        //根据数据源创建字符缓冲输入流对象
        BufferedReader br = new BufferedReader(new FileReader("myCharStream\\ConversionStreamDemo.java"));
        //根据目的地创建字符缓冲输出流对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\\Copy.java"));

        //读写数据,复制文件
        //使用字符缓冲流特有功能实现
        String line;
        while ((line=br.readLine())!=null) {
    
    
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        //释放资源
        bw.close();
        br.close();
    }

IO流小结

InputStream类是一个抽象类 ,是所有字节输入流类的父类。

OutputStream类是一个抽象类,是所有字节输出流的父类

InputStream的常见子类有:
FileInputStream:看这个名字就知道用于从文件中读取信息。
ByteArrayInputStream: 字节数组输入流,
ObjectInputStream:序列化时使用 一般和ObjectOutputStream一起使用
FilterInputStream: 过滤输入流,为基础的输入流提供一些额外的操作。

OutputStream的常见子类有:
FileOutPutStream: 文件输出流对文件进行操作
ByteArrayOutputStream: 字节数组输出流
ObjectOutputStream: 序列化时使用 一般和OjbectInputStream一起使用
FilterOutputStream:过滤输出流,为基础的输出流提供一些额外的操作。

看字节流和字符流的输入输出
图片
图片


现在你觉得自己学的怎么样呀,要是觉得自己学的还可以,可以尝试着去自己做个点名器了呀
结果类似这样
截图

写好了别来坑我呀,别有事可以钟无艳,但无事就别搞我!

你今天学废了吗?

猜你喜欢

转载自blog.csdn.net/qq_43325476/article/details/120656001