JAVA高级应用之IO流与文件的处理

文件讲解 IO流

文件练习题

从控制台输入一个字符串 该字符串是文件夹路径 计算这个文件夹的大小
public static long getLength(File file) {
        long sum = 0; //初始值为0
        File[] listFiles = file.listFiles();  // length()只能计算文件的长度 无法计算文件夹的的长度 里面包含文件的文件夹的长度也无法直接计算
        for(File file2 : listFiles) {
            if(file2.isFile()) {   
                sum = sum + file2.length();
            }else {
                sum = sum + getLength(file2);
            }
        }
        return sum;
    }
获取文件夹不是文件
public static File getFile() {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入有效文件路径:");
        String nextLine = scanner.nextLine();
        File file = new File(nextLine);
        if(!file.exists()) {
            System.out.println("文件不存在 - 无效地址");
            return getFile();
        }else if(file.isFile()){
            System.out.println("你输入的是个文件-请输入文件夹");
            return getFile();
        }else {
            return file;
        }
    }
从控制台输入一个字符串 该字符串是文件夹路径 删除这个文件夹
public static void deleteFile(File file) {
    File[] listFiles = file.listFiles();
    for(File file2 : listFiles) {
        if(file2.isFile()) {
            file2.delete(); //delete只能删除文件或者是空的文件夹 里面包含文件的文件夹,无法用delete删除,所有需要遍历,从里往外删
        }else {
            deleteFile(file2);
        }
    }
    file.delete();
}
理解
解释:file.listFiles()得到一个数组,这个数组是File类型的,但数组中既有文件夹还有文件,里面保存的是路径,需要遍历来区别;
isFile()是用来判断此File是否是个文件,isDirectory()是用来判断该File是否是个文件夹;file.list()得到的是保存文件名的数组,
单独的文件名字,不是路径,无法通过文件名找到该文件.
需求:
/* 
 * 输入一个文件夹路径 按层级关系 打印
a
    ooo.txt
    ppp.txt
    wl.txt
    www.txt
sss.txt
b
    ooo.txt
    ppp.txt
    wl.tx
    www.txt
*/
public static void 
public static void main(String[] args) {
        fun(new File("/Users/lanou/Desktop/Level"), 0);
    }
    public static void fun(File file,int level) {
        // level 判断是第几级文件夹
        String string = "";
        for(int i = 0; i < level; i++) {
            string = string + " ";
        }

        File[] listFiles = file.listFiles();  // 得到File路径 ,此路径即可能是文件也可能是文件夹
        for(File file2 : listFiles) {
            if(!file2.isHidden()) {  // 判断是否是隐藏文件,隐藏文件是电脑的问题,与我们无关
                System.out.println(string + file2.getName());
            }
            if(file2.isDirectory()) {
                fun(file2, level + 1);  //不能使用level++,因为返回来 再次开始的时候level还是得从0开始
            }
        }
    }
输入一个文件夹路径 用map记录类型出现的次数
package com.lanou3g;

import java.io.File;
import java.util.HashMap;
import java.util.Scanner;

// 输入一个文件夹路径 用map记录类型出现的次数
public class Demo03 {
    public static void main(String[] args) {
        File file = getDirFile();    // 调用getDirFile方法获取文件路径
        HashMap<String, Integer> map = new HashMap<>();  // 定义一个map集合
        fun(map, File);  

        printName(map);  // 打印map集合
    }
    public static void printName(HashMap<String, Integer> map) {
        for (String str : map.keySet()) {   //  循环遍历打印
            System.out.println(str);
            System.out.println(map.get(str));
        }
    }
    public static void fun(HashMap<String, Integer> map, File file) {
        File[] listFiles = file.listFiles();
        String string = null;
        for (File file2 : listFiles) {
            // 不是文件夹
            if(!file2.isFile()) {
                // 带着这个map继续
                fun(map, file2);
            }else {
                if(!file2.isHidden()) {  // 去掉系统产生的隐藏文件
                String name = file2.getName();  // 得到文件名字 如:t.txt文件
                String[] split = name.split("\\.");  // 文件名字很特殊,即使split可以分割,但任然需要用转义字符双反斜杠
                if(split.length == 1) {   // 如果数组长度是1,直接取这一位字符串
                // 这步有点多余,只要分割,最少长度为2
                    string = split[0];
                }else { 
                    string = split[split.length - 1];  // 取出数组最后一位后缀名
                }
                if(map.containsKey(string)) {  // 是否包含这个后缀
                    Integer integer = map.get(string);
                    integer++;   // 包含则取出数字加1
                    map.put(string, integer);
                }else {   // 不包含则创建,并附初值为1
                    map.put(string, 1);
                }
                }
            }
        }
    }

    public static File getDirFile() {
        Scanner scanner = new Scanner(System.in);
        // 是就返回 不是就重新输入
        while(true) {
            System.out.println("请输入一个文件夹的路径");
            String path = scanner.nextLine();
            // 利用输入的路径 创建文件对象去判断
            File file = new File(path);
            // 判断
            if(!file.exists()) {
                System.out.println("你输入的路径不存在 重新输入");
            }else if(file.isFile()) {
                System.out.println("你输入的是个文件 重新输入");
            }else {
                return file;
            }           
        }
    }
}

过滤器

文件过滤器(是个接口)  自定义规则
有返回值  返回false则被过滤 返回true则保留
创建一个类 实现FileFilter接口中的accept方法
FileFilter
package com.lanou3g;

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

public class Demo15 {
    public static void main(String[] args) {
        funny(new File("/Users/lanou/Desktop/level"));
    }
    public static void funny(File file) {
        File[] listFiles = file.listFiles(new Pacatur());
        for (File file2 : listFiles) {
            if(file2.isDirectory()) {
                funny(file2);
            }else {
                System.out.println(file2.getName());
            }
        }
    }
}
class Pacatur implements FileFilter{

    @Override
    public boolean accept(File pathname) {
        // TODO Auto-generated method stub
        if(pathname.isDirectory()) {
            return true;
        }
        return pathname.getName().endsWith("txt");
    }

}
FilenameFilter
package com.lanou3g;

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

public class Demo16 {
    public static void main(String[] args) {
        funny(new File("/Users/lanou/Desktop/level"));
    }

    public static void funny(File file) {
        File[] listFiles = file.listFiles(new Pacta());
        for (File file2 : listFiles) {
            if(file2.isDirectory()) {
                funny(file2);
            }else {
                System.out.println(file2.getName());
            }
        }
    }

}

class Pacta implements FilenameFilter{

    @Override
    public boolean accept(File dir, String name) {
        // TODO Auto-generated method stub
        File file = new File(dir, name);
        if(file.isHidden()) {
            return false;
        }
        if(file.isDirectory()) {
            return true;
        }
        return file.getName().endsWith("txt");
    }

}

字节流

参照物是自己的程序 ,输入输出是相对程序而言的,从程序中输出,输入到程序中

什么叫输出?
参照程序 以程序为中心 程序->文件 输出 output 写文件 从程序中写出到文件

什么叫输入?
文件到程序 -> 输入Input 读文件 读进来

OutPutStream 是抽象类 并且是所有输出流的父类
输入流测试-三个构造方法
构造方法1:write(int b)
构造方法2:write(byte[] b)
构造方法3:write(byte[] b, int off,int len)

写入文件流程:
1.绑定要写入的文件 或 文件路径
2.使用write方法写入
3.关闭资源

绑定数据的目的地(绑定要写入的文件)
该路径下没有该文件 会帮你创建该文件
每次只能写一个字节
代码示例
public static void main(String[] args) throws IOException { 
        File file = new File("/Users/lanou/Desktop/Test2/long.txt");
        FileOutputStream oStream = new  FileOutputStream(file);
        oStream.write(49);
        oStream.write(48);  
        oStream.write(48);

        byte[] b = {65,66,67,68};
        oStream.write(b);
        oStream.write(b, 1, 2);

        oStream.close();

    }
文件续写和换行
    File file = new File("/Users/lanou/Desktop/Test2/long.txt");
    FileOutputStream oStream = new FileOutputStream(file, true);

    oStream.write("hello".getBytes());
    oStream.close();
代码示例
        /*
         * 异常处理
         * io发生了异常 都需要停止程序 修改代码 抛出运行时异常
         */
        File file = new File("/Usersawef/lanou/Desktop/Test2/long.txt");
        // 增加作用域
        FileOutputStream oStream = null;
        try {
            // 创建了一个流
            // 只要是你手动创建了流 你就需要手动关闭它
            oStream = new FileOutputStream(file);
            //  写入
            oStream.write("hel".getBytes());
        } catch (FileNotFoundException e) {
            // 抛出运行时异常(直接停止掉程序)
            throw new RuntimeException("文件找不到");
        } catch (IOException e) {
            // 文件编写失败 直接停掉程序
            throw new RuntimeException("文件编写失败");       
        }finally {
            // 关闭资源
            try {
                // 非空判断 
                // 如果是空的 说明流创建失败了 失败了就不用关了
                if(oStream != null) {
                    oStream.close();
                }
            } catch (IOException e) {
                // 关闭资源失败 停止程序
                throw new RuntimeException("关闭失败");
            }
        }
字节输入流
代码示例1
每次读取一个字节 读到-1时停止
    public static void main(String[] args) throws IOException {
        File file = new File("/Users/lanou/Desktop/Test2/long.txt");
        FileInputStream fileInputStream = new FileInputStream(file);
        int i = fileInputStream.read();
        System.out.println(i);
        int i1 = fileInputStream.read();
        System.out.println(i1);
        int i2 = fileInputStream.read();
        System.out.println(i2);
        int i3 = fileInputStream.read();
        System.out.println(i3);
        int i4 = fileInputStream.read();
        System.out.println(i4);
        int i5 = fileInputStream.read();
        System.out.println(i5);
    }
代码示例2
循环读取数组中的元素 read每次循环只能调用一个
       File file = new File("/Users/lanou/Desktop/Test2/long.txt");
        FileInputStream fileInputStream = new FileInputStream(file);
        int i;
        while((i = fileInputStream.read())!= -1) {
            System.out.println(i);
        }
代码示例3
    File file = new File("/Users/lanou/Desktop/Test2/long.txt");
    FileInputStream iStream = new FileInputStream(file);
    // 声明了一个长度为2的 空的 字节数组
    // 读取时 会把读出来的字节放进字节数组存储
    byte[] b = new byte[2];
    int i1 = iStream.read(b);
    System.out.println(i1);
    // 利用字符串的构造方法 直接打印字符串
    System.out.println(new String(b));

    i1 = iStream.read(b);
    System.out.println(i1); // 2
    // 利用字符串的构造方法 直接打印字符串
    System.out.println(new String(b)); //cd

    i1 = iStream.read(b);
    System.out.println(i1);
    System.out.println(new String(b));

    i1 = iStream.read(b);
    System.out.println(i1);
    // 利用字符串的构造方法 直接打印字符串
    System.out.println(new String(b));
    iStream.close();
iStread(b) 打印的是有效的长度,定义的数组长度不宜过大也不宜过小,1024*5比较合适,当读取到的字符串无效时,
指针指到的位置为空,无法覆盖数组中的元素,最后输出的字符串会一直相同,同时iStream.read(b)的长度为也变成-1.
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值