Java学习 17 IO流(一)

File类

        // 创建File对象
        // File f1 = new File("D:\\文档\\项目表.xlsx")
        File f1 = new File("D:"+File.separator +"文档"+File.separator+"项目表.xlsx");
        System.out.println(f1.length());

注意:

File对象既可以代表文件,也可以代表文件夹

File封装的对象仅仅是一个路径名,这个路径可以是存在的,也可以是不存在的

绝对路径、相对路径

绝对路径:从盘符开始

        // 绝对路径
        File f4 = new File("F:\\F盘资料\\学习web\\java\\1\\javasepromax\\day17-file-io-app"+
                "\\src\\com\\dong\\abc.txt");

相对路径:不带盘符,默认直接到当前工程下的目录寻找文件

  // 相对路径
        File f4 = new File("day17-file-io-app\\src\\com\\dong\\abc.txt");
        System.out.println(f4.length());

File提供的判断文件类型、获取文件信息功能

public class Test1 {
    public static void main(String[] args) {
        // 创建方个File文件
        File f1 = new File("D:\\文档\\项目表.xlsx");
       // File f1 = new File("D:\\文档");
        // exists() 判断文件是否存在
        System.out.println(f1.exists()); // true
        // isFile() 判断当前文件是否是文件
        System.out.println(f1.isFile()); // true
        // isDirectory() 判断当前是否是文件夹
        System.out.println(f1.isDirectory()); // false
        //getName() 获取当前文件名字
        System.out.println(f1.getName()); //项目表.xlsx
        // length() 获取文件大小(对于文件夹只能判断文件夹本身大小,不能判断其内容大小)
        System.out.println(f1.length());
        // lastModified() 获取文件的最后修改时间
        System.out.println(f1.lastModified());
        //LocalDateTime time = LocalDateTime.parse(f1.lastModified());
        SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(sdf.format(f1.lastModified()));
        // getPath() 获取创建文件对象时,使用的路径
        File f4 = new File("day17-file-io-app\\src\\com\\dong\\abc.txt");
        System.out.println(f1.getPath());
        System.out.println(f4.getPath());
        // getAbsolutePath() 获取绝对路径
        System.out.println(f4.getAbsoluteFile());
    }
}

File类删除文件功能

public class Test2 {
    public static void main(String[] args) throws Exception {
        // createNewFile() 创建一个新文件
        File f1 = new File("D:\\文档\\dong.txt");
        System.out.println(f1.createNewFile()); // 不存在创建成功 存在创建失败
        // mkdir() 用户创建文件夹 只能创建一级文件夹
        File f2 = new File("D:\\文档\\aa");
        System.out.println(f2.mkdir());
        // mkdirs() 用户创建文件夹 能创建多级
        File f3 = new File("D:\\文档\\bb");
        System.out.println(f3.mkdirs());
        // delete() 删除文件、空文件夹 非空不行
        System.out.println(f1.delete()); //true
        System.out.println(f2.delete());  // true
        System.out.println(f3.delete()); // false
    }
}

File类遍历文件夹

public class Test3 {
    public static void main(String[] args) {
        // list() 当前文件夹下一级文件名称 到一个字符串数组中
        File f1 = new File("F:\\F盘资料\\学习web\\java");
        for (String s : Objects.requireNonNull(f1.list())) {
            System.out.println(s);
        }
        // listFiles() 获取挡墙目录下所有的一级文件对象到一个文件数据中
        File[] files = f1.listFiles();
        for (File file : files) {
            System.out.println(file);
        }
    }
}

使用listFile方法时的注意事项:

  • 当主调的文件,或者路径不存在时,返回null
  • 当主调是空文件夹时,返回一个长度为0的数组
  • 当主调是一个有内容的文件夹时,将里面所有一级文件盒文件夹的路径放在File数组中返回
  • 当主调是一个文件夹,且里面有隐藏文件时,将里面所有文件盒文件夹的路径放在File数组中返回,包含隐藏文件
  • 当主调是一个文件夹,但是没有权限访问该文件夹时,返回null

递归

反复调用自身


public class Recursion7 {
    public static int totalNumber;
    public static int lastBottles;
    public static int lastCoverNumber;

    public static void main(String[] args) {
        // 啤酒两元一瓶 四个盖子可以换一瓶 两个空瓶可以换一瓶 10元可以喝几瓶
        buyBear(10);
    }

    public static void buyBear(int money) {
        int buyNumber = money / 2;
        totalNumber += buyNumber;

        int newMoney = ((buyNumber + lastBottles)/2 + (buyNumber + lastCoverNumber) /4) * 2;
        lastBottles = (buyNumber + lastBottles) % 2;
        lastCoverNumber = (buyNumber + lastCoverNumber) % 4;
        if (newMoney < 2) {
            System.out.println("一共可以买:" + totalNumber + "瓶");
            System.out.println("瓶盖剩余:" + lastCoverNumber);
            System.out.println("瓶子剩余:" + lastBottles);
        } else {
            buyBear(newMoney);
        }
    }
}

标注ASCII字符集

美国信息交换标准代码,包括英文、符号等

标准ASCII使用1个字节存储一个字符,首尾是0,总共可表示128个字符,对美国佬来说完全够用

GBK(汉字内码扩展规范,国标)

汉字编码字符集,包含了2万多个汉字等字符,BGK中一个中文字符编码成两个字节的形式存储

注意:GBK兼容ASCII字符集

GBK规定:汉字第一个字节的第一位必须是1,ASCII首尾是0 用于区分

UTF-8

是Unicode字符集的一种编码方案,采取可变长度编码方案,共分四个长度区:1个字节,2个字节,3个字节,4个字节

英文字符、数字等只占1字节(兼容标准ASCII编码),汉字字符占用3个字节

ASCII字符集:只有英文、数字、符号等,占1个字节

GBK字符集:汉字占2个字节,英文、数字占一个字节

UTF-8字符集:汉字占3个字节,英文、数字占一个字节

注意1:字符编码时使用字符集,和解码时使用的字符集必须一致,否则会出现乱码

注意2:英文,数字一般不会乱码,因为很多字符集都兼容了ASCII编码

public class Test {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String data = "a我b";
        // 编码 data.getBytes() 可以填参数 参数为编码形式
        byte[] bytes = data.getBytes(); // 默认的utf-8编码
        System.out.println(Arrays.toString(bytes));

        byte[] bytes1 = data.getBytes("GBK");
        System.out.println(Arrays.toString(bytes1));

        // 解码 直接new String() 可以填两个参数 第二个参数指定编码形式
        String s1 = new String(bytes);
        System.out.println(s1);

        String s2 = new String(bytes1, "GBK");
        System.out.println(s2);

    }
}

IO流

总结流的四大类

字节输入流:以内存为基准,来自磁盘文件/网络中的数据以字节的形式读入到内存中去的流(InputStream)

字节输出流:以内存为基准,把内存中的数据以字节写出到磁盘文件或者网络中去的流(OutputStream)

字符输入流:以内存为基准,来自磁盘文件/网络中的数据以字符的形式读入到内存中去的流(Reader)

字符输出流:以内存为基准,把内存中的数据以字符写出到磁盘文件或者网络介质中去的流(Writer)

FileInputStream(文件字节输入流) 

read() 一个字符一个字符读取

public class FileInputStreamTest1 {
    public static void main(String[] args) throws IOException {
//        InputStream is = new FileInputStream(new File("day17-file-io-app\\src\\abc.txt"));
        // 简化写法
        InputStream is = new FileInputStream("day17-file-io-app\\src\\abc.txt");
        // 读取文件的字节数据 每次读取一个 如果读取完成 就会返回-1
//        int b1 = is.read();
//        System.out.println((char) b1);
//        int b2 = is.read();
//        System.out.println((char) b2);
//        int b3 = is.read();
//        System.out.println((char) b3);
//        int b4 = is.read();
//        System.out.println(b4);
        int b;
        while ((b = is.read()) !=-1){
            System.out.print((char) b);
        }
        // 读取性能差
        // 取得汉字乱码
        // 流使用完了要关闭
        is.close();
    }
}

read(byte[] bytes) 

public class FileInputStreamTest2 {
    public static void main(String[] args) throws IOException {
        // 创建一个字节输入流对象 代表字节输入流管道与原文件接通
        InputStream is = new FileInputStream("day17-file-io-app\\src\\abc.txt");
        // 开始读取文件中的字节
//        byte[] buffer = new byte[3];
//        int len = is.read(buffer);
//        String rs = new String(buffer);
//        System.out.println(rs);
//        System.out.println("读取字节数"+len);
//        int len1 = is.read(buffer);
//        读取多少 就倒出多少
//        String rs1 = new String(buffer, 0, len1);
//        System.out.println(rs1);
//        System.out.println("读取字节数"+len1);
//        int len2 = is.read(buffer);
        String rs2 = new String(buffer, 0, len2);
        System.out.println(rs2);
//        System.out.println(len2);
        byte[] buffer = new byte[3];

        int len;
        while ((len=is.read(buffer)) !=-1){
            String rs = new String(buffer, 0 , len);
            System.out.print(rs);
        }
        // 性能提高了
        // 汉字可能会出乱码
        is.close();
    }
}

文件字节输入流:一次读取完全部字节

方式一:自己定义一个字节数组与被读取的文件大小一样大,然后使用该字节数组,一次性读取全部字节

public class FileInputStreamTest3 {
    public static void main(String[] args) throws Exception {
        InputStream is = new FileInputStream("day17-file-io-app\\src\\test03.txt");
//        File f = new  File("day17-file-io-app\\src\\test03.txt");
//        long size = f.length();
//        byte[] buffer = new byte[(int) size];
//        int len = is.read(buffer);
//        String rs = new String(buffer, 0, len);
//        System.out.println(rs);
//        System.out.println(size);
//        System.out.println(len);
        byte[] buffer = is.readAllBytes();
        System.out.println(new String(buffer));
        is.close();
    }
}

适用于文件复制

FileOutputStream

public class FileOutputStreamTest1 {
    public static void main(String[] args) throws Exception {
        // 创建一个字节输出流管道月目标文件接通
        OutputStream os = new FileOutputStream("day17-file-io-app\\src\\output04.txt", true);

        // 每次写入一个数据出去
        os.write(97);
        os.write('b');
        // 写入汉字 乱码
//        os.write('磊');
        // 用字符数组
        byte[] bytes = "我爱中国abc".getBytes();
        os.write(bytes);
        os.write(bytes, 0, 12);
        os.write("\r\n".getBytes());
        os.close();
    }
}

复制文件

public class CopyTest {
    public static void main(String[] args) throws Exception {
        // 文件复制
        // 创建字节输入流
        // InputStream is = new FileInputStream("C:\\Users\\dongyan\\Pictures\\Saved Pictures\\flower.webp");
         InputStream is = new FileInputStream("day17-file-io-app\\src\\test03.txt");
        // 创建自己输入流
//        OutputStream os = new FileOutputStream("day17-file-io-app\\src\\flower.webp");
        OutputStream os = new FileOutputStream("day17-file-io-app\\src\\test03copy.txt");
        // 创建一个字节数组
        byte[] buffer = new byte[1024];
        // 从字节输入
        int len;
        while ((len= is.read(buffer))!=-1){
            os.write(buffer, 0, len);
        }
        os.close();
        is.close();
        System.out.println("复制完成");
    }
}

try-catch-finally

try {

                ... ...

} catch(Execption e){

                e.printStackTrace();

}finally{

                执行内容

}

finally代码区的特点:无论try中的程序是正常执行了,还是出现了异常,最后都一定会执行finally区,除非JVM终止

作用:一般用于在程序执行完成后进行资源的释放操作(专业级做法)。

public class Test1 {
    public static void main(String[] args) {
//        try {
//            System.out.println(10 / 2);
//            // return;
//            // System.exit(0);
//        } catch (Exception e){
//            e.printStackTrace();
//        } finally {
//            System.out.println("=======finally执行了一次======");
//        }
        // 先执行finally的内容在返回值
        System.out.println(chu(10, 5));
    }
    public static int chu(int a, int b){
        try {
            return a / b;
        } catch (Exception e){
            e.printStackTrace();
            return -1;
        } finally {
            // 不要在finally里面返回数据 否则就会一直返回finally里面的返回值
            // return 111;
            System.out.println("finally执行了");
        }
    }
}

try-with-resource

try(定义资源1;定义资源2;...){

                可能出现异常的代码;

} catch(异常类名 变量名){

                异常的处理代码;

}

public class Test3 {
    public static void main(String[] args) {
        try(
                // 这里只能放置资源对象 什么是资源?资源都是会实现AutoCloseable接口
                // 用完之后,会自动调用其close方法完成资源的释放操作
                InputStream is = new FileInputStream("day17-file-io-app\\src\\test03.txt");
                OutputStream os = new FileOutputStream("day17-file-io-app\\src\\test05copy.txt");
        ) {
            // 文件复制
            // 创建一个字节数组
            byte[] buffer = new byte[1024];
            // 从字节输入
            int len;
            while ((len= is.read(buffer))!=-1){
                os.write(buffer, 0, len);
            }
            System.out.println("复制完成");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

该资源使用完毕后,会自动调用其close()方法,完成对资源的释放!

()中只能放置资源,否则报错

什么是资源呢?

资源一般指的是最终实现了AutoCloseable接口

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值