03-Java核心类库_IO

目录

三,IO

1,java.io.File

1.1 常用构造方法

1.2 其他常用方法

1.3 字段

2,文件遍历案例

3,文件过滤器

应用实例

改进

4,相对与绝对路径

5,流概述

6,java.io.OutputStream

7,java.io.FileOutputStream

8,java.io.FileInputStream

8.1 常用方法

8.2 常见子类——FileInputStream

9,文件加密和解密工具

10,字节流读取文字

11,字符输出

12,字符读取

13,flush刷新管道

14,字节转换字符流

15,Print与BufferedReader

15.1 打印流

15.2 缓存读取流

16,收集异常日志

17,properties

17.1 概述

17.2 常用方法

18,序列化技术

18.1 概述

18.2 序列化

18.3 反序列化

19,try-with-resources

19.1 原因

19.2 解决方法


三,IO

1,java.io.File

1.1 常用构造方法

1,构造方法声明

2,File​(String pathname)

3,File​(File parent, String child)

4,File​(String parent, String child)

1.2 其他常用方法

1.3 字段

不同操作系统路径分隔符可能不同,"//"不会适用于所有操作系统

2,文件遍历案例

package zuoye;

import java.io.File;


public class Demo4 {
    public static void main(String[] args) {
        File e = new File("e://");
        File[] files = e.listFiles();    // 获得E盘下所有文件
        listFile(files);                 // 调用遍历的方法

    }

    public static void listFile(File[] files){
        if(files!=null&&files.length>0){ // 文件存在且不为空
            for (File file:files) {
                if(file.isFile()){       // 是文件
                    if(file.getName().endsWith(".avi")){    // 选择avi后缀的
                        if(file.length()>100*1024*1024)     // 文件大小大于100M
                        System.out.println("找到了一个avi文件"+file.getAbsolutePath());
                    }
                }else {                  // 是文件夹
                    File[] files2 = file.listFiles();
                    listFile(files2);    // 递归
                }
            }
        }

    }
}


3,文件过滤器

应用实例

package com.kaikeba;

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

public class Demo1 {
    public static void main(String[] args) throws IOException {
        File e = new File("d://");
        listFiles(e);
    }
    public static void listFiles(File file){    // 自定义的方法
        if(file != null && file.length() != 0){ // 文件存在且不为空
            // 1,创建一个过滤器,并描述规则
            FileFilter filter = new AVIFileFilter();
            // 2,通过文件获取子文件夹
            File [] files = file.listFiles(filter); // 对象的方法
            // 3,递归遍历所有文件
            for(File f : files) {
                if(f.isDirectory()) {
                    listFiles(f);
                }else {
                    System.out.println("发现一个txt文件:" + f.getAbsolutePath());
                }
            }
        }
    }
    static class AVIFileFilter implements FileFilter{    // 为实现过滤器接口 需要定义一个类 这里为静态内部类
        @Override
        public boolean accept(File pathname) {
            // 只保留txt文件和文件夹
            if(pathname.getName().endsWith(".txt") || pathname.isDirectory()) {
                return true;
            }
            return false;
        }
    }
}

改进

用匿名内部类实现FileFilter接口,并直接作为参数,调用listFiles获得筛选过后的文件

package com.kaikeba;

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

public class Demo1 {
    public static void main(String[] args) throws IOException {
        File e = new File("d://");
        listFiles(e);
    }
    public static void listFiles(File file){
        if(file != null && file.length() != 0){ // 文件存在且不为空
            File [] files = file.listFiles(new FileFilter() {   // 通过匿名内部类作为参数的方法 实现过滤
                @Override
                public boolean accept(File pathname) {
                    // 只保留txt文件和文件夹
                    if(pathname.getName().endsWith(".txt") || pathname.isDirectory()) {
                        return true;
                    }
                    return false;
                }
            });
            // 递归遍历所有文件
            for(File f : files) {
                if(f.isDirectory()) {
                    listFiles(f);
                }else {
                    System.out.println("发现一个txt文件:" + f.getAbsolutePath());
                }
            }
        }
    }
}

4,相对与绝对路径

绝对路径:以盘符开始,是一个完整的路径,例如c://a.txt
相对路径:java中是相对于项目目录路径,这是一个不完整的路径,在Java开发中很常用    例如  a.txt

5,流概述

package com.java.demo;


import java.io.*;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

/**
 * @author liweijie
 */
public class Demo {
    /**
     * IO流概述
     *  可以将这种数据传输操作,看做一种数据的流动 , 按照流动的方向分为输入Input和输出Output
     *  Java中的IO操作主要指的是 java.io包下的一些常用类的使用. 通过这些常用类对数据进行读取(输入Input) 和 写出(输出Output)
     *
     * IO流的分类:
     *  按照流的方向来分,可以分为:输入流和输出流.
     *  按照流动的数据类型来分,可以分为:字节流和字符流
     *
     *     字节流:(顶级父类)
     *          -   输入流 :   InputStream
     *          -   输出流 :   OutputStream
     *     字符流:(顶级父类)
     *          -   输入流 :   Reader
     *          -   输出流 :   Writer
     *
     *
     * 一切皆字节:
     *      计算机中的任何数据(文本,图片,视频,音乐等等)都是以二进制的形式存储的.
     *      在数据传输时 也都是以二进制的形式存储的.
     *      后续学习的任何流 , 在传输时底层都是二进制.
     * @param args
     */
    public static void main(String[] args) throws FileNotFoundException {


    }

}

6,java.io.OutputStream

     *      一切皆字节:
     *      计算机中的任何数据(文本,图片,视频,音乐等等)都是以二进制的形式存储的.
     *      在数据传输时 也都是以二进制的形式存储的.
     *      后续学习的任何流 , 在传输时底层都是二进制.

OutputStream是抽象类

注意:

写完一定要关闭close;

7,java.io.FileOutputStream

其中append为true则表示,在文件末尾添加数据,否则表示重新写入数据

package zuoye;

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


public class Demo6 {
    public static void main(String[] args) throws IOException {
        //OutputStream
        FileOutputStream fos = new FileOutputStream("c://a.txt"); // 没有添加append参数,表示默认false 即覆盖原数据
        byte[] bytes = {65,66,67,68,69};
        fos.write(bytes);
        fos.close();                //写在哪在哪关闭
        System.out.println("已经写出");

    }
}

通过字符串+getBytes函数,获得字节数组:

8,java.io.FileInputStream

8.1 常用方法

8.2 常见子类——FileInputStream

1)构造方法

2)read()方法

3)read​(byte[] b)

注:代码中漏掉了fis.close(),这种错误一定要避免!!!

改进方法(记录读取到的字节数)

9,文件加密和解密工具

示例代码

package com.kaikeba;

import java.io.*;
import java.util.Scanner;

public class Demo1 {
    public static void main(String[] args) throws IOException {
        System.out.println("请输入文件路径名:");
        Scanner input = new Scanner(System.in);
        String s = input.nextLine();
        File oldFile = new File(s);
        File newFile = new File(oldFile.getParent() + "_new_File_" + oldFile.getName());
        FileInputStream fis = new FileInputStream(oldFile);
        FileOutputStream fos = new FileOutputStream(newFile);
        while (true) {
            byte b = (byte) fis.read();
            if(b == -1) {
                break;
            }
            fos.write(b ^ 10);// 加密(一个数异或两次,还是本身)
        }
        fis.close();
        fos.close();
        System.out.println("加密/解密结束");
    }

}

加密(新文件的命名方式修改了,但截图中并没有纠正过来)

再次运行程序进行解密(正确修改)

10,字节流读取文字

由于工程使用的是UTF-8字符编码,所以在读取工程中的文本文件时,不会出现乱码

由于提前限定了一次读取的字节数为10,所以出现了读取不到一个完整汉字的情况,因而出现乱码。但是UTF-8使用动态编码表,由于提前不知道每个字符需要多少字节,所以此方法不行。

所以下面引入了字符流,用来解决读取半字的问题

11,字符输出

字符流用来操作文字,而字节流可以操作任何文件,所以字节流更加常用。

注意:

决定是否在原文件基础上追加的,是声明字符流对象是的append属性(为true则是追加模式);

append与write在实际实现上,没有区别,但是append会返回Writer对象;

append方法的返回值(Writer类型)可以强转为该对象(FileWriter类型),所以可以继续调用append,因而称为“追加”;

12,字符读取

基本使用方法同字节流。

13,flush刷新管道

字符输出时,以字符为单位,但计算机中都是以字节为单位。当一个字符占用多个字节时,字符输入流未读取单个字符全部字节之前,会将已读取字节放入缓存;

字符输出流fw.flush()会将缓存中字符强制写入到文件中,fw.close()也会有此效果;

如果不执行的话,就不会将字符写入文件中,如图:

14,字节转换字符流

转换流。将字节流装饰为字符流:使用了装饰者模式;

为什么要使用字节流+转换流?直接字符流不香吗?:由于平常使用时,可能获取的是字节流,所以才有这种转换方式

15,Print与BufferedReader

15.1 打印流

1)打印字节流与打印字符流

打印字节流

打印字符流(记得flush或close)

打印字节流和打印字符流在使用上差别不大,但字符流需要调用flush,否则不会写入到文件中;

2)字节流转换为打印流

15.2 缓存读取流

将字符输入流转换为带有缓存可以一次读取一行的缓存字符读取流

字节流-》字符流-》缓存读取流

当读取到末尾时,会返回null

 

16,收集异常日志

普通的异常控制台显示

可以将异常信息保存在txt文档中,并加上日期,便于后期核查

17,properties

17.1 概述

properties继承HashTable属于Map集合(键值对),但其扩展部分含有IO相关用法(配置文件)

17.2 常用方法

1)store方法:将properties对象内容写入字节流/字符流所指的文件中

2)load方法:将字节流/字符流指向的文件内容加载到properties对象中

3)get与getProperty

get返回Object对象,getProperty返回字符串。

18,序列化技术

18.1 概述

由于垃圾回收机制的存在,一些属性或对象,在程序关闭之后,便消失,无法重复利用,所以有人在想能不能将把对象完整的存储在文件中,使用时再取出来,即对象在内存中存储的字符序列(看上去像是乱码);

将文件中的对象读取到程序中来,就是反序列化;

虽然序列化很方便,但是却十分容易产生Bug(占Bug总数将近三分之一),所以Java官方提出近几年将要进行整改,建议大家不要使用此方法;(了解下也是有必要的)

18.2 序列化

Java官方规定,所有对象均不能序列化,想要序列化,需添加标记

添加标记:实现接口Serializable。添加代码后没有任何飘红,即说明不需要实现任何方法,因此这个接口被称为标记接口。

18.3 反序列化

19,try-with-resources

19.1 原因

1)在文件流使用完毕后需要关闭

2)为了使close一定被执行,需要将其放在finally中

3)所以需要将fr提到try之前,但仍可能产生空指针异常

4)继续try-catch处理

5)综上,这么多步骤就是为了读入一个字符

19.2 解决方法

1)jdk1.7之前:在try中new的对象会在try或catch块执行完毕后执行close。但要求,能使用此方法的类必须实现Closeable或AutoCloseable两个接口

2)但是,如果后面还有代码块需要用到try中的对象时,就显得不方便了。JDK9进行了改进

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值