IO常用方法和过滤器,字节流,字符流

IO

  • input:读入,将磁盘上的数据读取到内存中
  • output:写出,将内存中的数据写到磁盘
  • 内存:软件执行的空间。速度快,造价高
  • 磁盘中:可以永久保存数据,存放数据、文件、文件夹。空间大,速度慢

IO流

  • 流:数据流。内存流向磁盘
  • I:输入流:将磁盘数据以流的形式读取到内存
  • O:输出流:将内存中的数据以流的形式写入磁盘中。

路径

  • 绝对路径:完整的路径,从盘符开始,到具体的文件或者文件夹的路径
  • 相对路径:相对于当前路径的路径。以当前路径为基础。目标文件路径
    • 退出当前路径…/。当前路径./;

File

  • 文件:java中表示文件或者文件夹的类,在java中,将文件或者文件夹作为一个File类的对象
  • 操作这个FIle对象,你在操作这个文件
  • 这个类是独立于系统的。无论你的电脑是win或者Mac,脱离与系统的。
静态属性
  • pathSeparator:系统默认的路径分隔符,是一个封号,字符串表示,在Unix上是冒号表示
  • pathSeparatorChar:系统默认的路径分隔符,是一个封号,字符表示
  • separator:系统默认的名称分隔符,是一个反斜杠,字符串表示,在Unix是正斜杠
  • separatorChar:系统默认的名称分隔符,是一个反斜杠,字符表示
构造方法
	@Test
    public void test03() {
        //接受一个字符串对象,表示文件或者文件夹的路径名,可以抽象出一个File对象
        File parent = new File("f:\\Python");
        //接受一个file对象,和一个字符串的文件名,组合成一个完整的路径
        File file = new File(parent,"pro01");
        System.out.println(file.getAbsolutePath());
        //接受两个字符串的路径,第一个是父路径,第二个是子路径
        File file1 = new File("f:\\Python","pro02");
        System.out.println(file1.getAbsolutePath());
    }
  • 构造中的路径可以是不存在的。路径存在的情况下,文件或者文件夹可以是不存在的
  • 盘符不存在的情况,如果操作方法会报错
  • 路径存在,文件或者文件夹不存在,操作没有问题的
常用方法
  • 新建的方法
    • createNewFile():新建一个文件。
    • mkdir():新建一个文件夹,单级
    • mkdirs():新建一个文件夹,多级
  • 查看的方法
    • canRead():查看文件或文件夹是否可读
    • canWrite():查看文件是否可写
    • exists():查看文件或文件夹是否存在
    • getAbsoulutePath():返回file对象的绝对地址
    • getPath():返回构造中的路径
    • getName():返回路径的后缀名称
    • getparentFile():返回父路径的File对象
    • getParent():返回父路径的字符串表示
    • isFile():查看是否是一个文件
    • siDirectory():查看是否是一个文件夹
    • length():返回文件的大小
    • list():
    • listFile():
  • 删除的方法
    • delete():可以删除文件或者文件夹,只能删除文件或者空文件夹
  • 修改的方法
    • setReadable():修改可写
    • setWritable():修改可读
    • setReadOnly():修改只读
	@Test
    public void test04() {
        File file = new File("f:\\fileDemo");
        //不管路径存在与否,只看属性,判断文件是否可读
        //如果路径不存也是false
        System.out.println(file.canRead());
        //判断是否是可执行文件
        System.out.println(file.canExecute());
        //判断文件是否可写
        System.out.println(file.canWrite());
        //判断文件名字的字符串的大小
        file.compareTo(new File("u:\\fileDemo"));
        //根据你给定的路径创建文件,如果该文件不存在,如果路径不存在,报错
        try {
            boolean newFile = file.createNewFile();
            System.out.println("newFile = " + newFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //删除文件,无论文件是否为空,直接删除,不走回收站
        boolean delete = file.delete();
        System.out.println("delete = " + delete);
        //如果file对象是一个文件夹,只能删除空的。如果文件夹有东西。不能删除的
        boolean delete1 = new File("F:\\testdelete").delete();
        System.out.println("delete1 = " + delete1);
        //判断你路径表示的文件或者文件夹是否存在
        boolean exists = file.exists();
        System.out.println("exists = " + exists);
        //返回file对象表示的绝对路径
        String absolutePath = file.getAbsolutePath();
        System.out.println("absolutePath = " + absolutePath);
        try {
            //返回绝对路径,可以单击直接打开路径表示的文件或者文件夹
            String canonicalPath = file.getCanonicalPath();
            System.out.println("canonicalPath = " + canonicalPath);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //返回构造中给的路径名称
        String name = file.getName();
        System.out.println("name = " + name);
        //返回路径,跟构造中一样,与File类的toString方法一样的
        String path = file.getPath();
        System.out.println("path = " + path);
        //返回父路径的File对象
        File parentFile = file.getParentFile();
        System.out.println("parentFile = " + parentFile);
        //返回父路径的字符串表示的路径
        String parent = file.getParent();
        System.out.println("parent = " + parent);
        //判断file对象表示的是否是一个文件夹
        boolean directory = file.isDirectory();
        System.out.println("directory = " + directory);
        //判断file对象表示的是否是一个文件
        boolean file1 = file.isFile();
        System.out.println("file1 = " + file1);
        //判断是否是隐藏文件
        boolean hidden = file.isHidden();
        //返回最后一次修改的时间距离1990年的毫秒值
        long l = file.lastModified();
        //返回文件的大小,文件夹没有大小的,返回的是字节数
        long length = file.length();
        System.out.println("length = " + length);
        //创建文件夹,如果文件夹不存在。路径没有的话报错,只能创建一级目录
        boolean mkdir = file.mkdir();
        System.out.println("mkdir = " + mkdir);
        //创建新的文件夹,可以创建多级目录
        file.mkdirs();
        //文件重命名,移动文件,如果路径相同,就是重名名,如果路径不同,就复制文件
        //file.renameTo(new File(""));
        //修改可读属性
        file.setReadable(true);
        //修改可写属性
        file.setWritable(true);
        //只读,修改文件属性为只读
        file.setReadOnly();
    }
@Test
    public void test05() throws IOException {
        File file = new File("f:\\XDjob");

        //返回file下的所有的文件或者文件夹的名称,在数组中
        String[] list = file.list();
        for (String s : list) {
            System.out.println("s = " + s);
        }
        System.out.println("*************************");
        //返回file下的所有的文件或者文件夹的file对象,在数组中
        File[] files = file.listFiles();
        for (File file1 : files) {
            System.out.println("file1 = " + file1);
        }
    }

文件过滤器

  • 过滤特定文件或文件夹

  • FileFiter:一个参数,File类型的

    public void test07(File file) {
            if (file.isFile()) {
                if (file.getAbsolutePath().endsWith(".md")) {
                    System.out.println(file);
                }
                return;
            }
    
            File[] files = file.listFiles(new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    if (pathname.isDirectory()||pathname.getAbsolutePath().endsWith(".md")) {
                        return true;
                    }
                    return false;
                }
            });
    
            for (File file1 : files) {
                if (file1.isFile()) {
                        System.out.println(file1);
                } else {
                    test07(file1);
                }
            }
        }
    		File[] files = file.listFiles(f->{
                if (f.isDirectory()||f.getAbsolutePath().endsWith(".md")) {
                    return true;
                }
                return false;
            });
    
  • FileNameFilter():两个参数,File dir,String name;dir父路径,name,文件或者文件夹名称

        public void test07(File file) {
            if (file.isFile()) {
                if (file.getAbsolutePath().endsWith(".md")) {
                    System.out.println(file);
                }
                return;
            }
    
            File[] files = file.listFiles(new FilenameFilter() {
                @Override
                public boolean accept(File dir, String name) {
                    if (new File(dir,name).isDirectory()||name.endsWith(".md")) {
                        return true;
                    }
                    return false;
                }
            });
            for (File file1 : files) {
                if (file1.isFile()) {
                        System.out.println(file1);
                } else {
                    test07(file1);
                }
            }
        }
    
  • list()中只能用第二个

  • listFiles()中两个过滤器都可以使用

递归

  • 语法:方法在内部调用自己。

  • 好处:可以将复杂的n阶问题,简化成一或二阶问题

  • 理论上所有的循环都可以写成递归

  • 所有的递归都要有一个出口

  • 构造方法不能用递归

  • 注意

    • 递归是很容易出错的。尽量少用
    • 即使递归没有错的,运行依然可能报错
  • 求1+2+。。。n的和

    • 等于n+(n-1的和)

    • n-1+(n-2的和)

      public int add2(int n) {
              if (n==1) {
                  return 1;
              }
              return n+add2(n-1);
          }
      
  • 直接递归

  • 间接递归

  • 用递归求n的阶乘

  • 递归遍历文件夹

    public void test02(){
            out(new File("G:/project"));
        }
    
        public void out(File file){
            if(file.isFile()){
                System.out.println(file);
                return;
            }
            File[] files = file.listFiles();
            for (File file1 : files) {
                if (file1.isFile()) {
                    System.out.println(file1);
                } else {
                    out(file1);
                }
            }
        }
    

    递归遍历删除文件夹

    	@Test
        public void test01(){
            boolean deletes = deletes(new File("G:\\线下"));
            System.out.println("deletes = " + deletes);
        }
    
        public boolean deletes(File file){
            if(file.isFile()){
                file.delete();
                return true;
            }
            File[] files = file.listFiles();
            for (File file1 : files) {
                if(file1 != null){
                    if(file1.isFile()){
                        file1.delete();
                    }else{
                        deletes(file1);
                    }
                }
            }
            file.delete(); // 删除剩余空文件
            return true;
        }
    

IO流框架

  • I:从其他设备到内存
  • O:从内存到其他设备
  • 流的分类
    • 按照流向分:
      • 输入流:从其他设备指向内存的。读入
      • 输出流:从内存指向其他设备。写出
    • 按照流的单位分:
      • 字节流:流操作的基本数据单位是字节
      • 字符流:流操作的基本数据单位是字符
    • 按照功能分:
      • 节点流:流的父类/接口
      • 功能流:具体的子类/实现类

字节流

  • 字节输入流:inputStream、以字节为单位的输入流
 	@Test
    public void test07() {
        InputStream input = null;
        try {
            input = new FileInputStream("F:\\demo.txt");
            int tem;
            while ((tem = input.read())!=-1) {
                System.out.println(tem);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (input!=null) {
                    input.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    @Test
    public void test08() {
        try {
            InputStream input = new FileInputStream("F:\\demo.txt");
            byte[] arr = new byte[10];
            int tem;
            while ((tem = input.read(arr))!=-1) {
                System.out.println(new String(arr,0,tem));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
        try (InputStream input = new FileInputStream("F:\\demo.txt")){
            
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
  • 字节输出流:outputStream、以字节为单位的输出流

    • 如果文件不存在,新建文件。如果路径不存在,报错
    • 如果文件存在呢。清空文件,然后再写入。
   @Test
    public void test10() {
        try {
            OutputStream stream = new FileOutputStream("F:\\abcdef.txt");
            stream.write(97);
            byte[] arr = {98,99,0,0};
            stream.write(arr);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 电脑保存的数据就是字节形式的0和1,字节流就是一个字节一个字节的操作。字节流是万能的。多用于多媒体数据传输
  • 字节流复制图片
//复制图片
    @Test
    public void test05(){
        InputStream input = null;
        OutputStream out = null;
        try {
            input = new FileInputStream("F:\\图片\\_20201010181131.jpg");
            out = new FileOutputStream("G:\\图片.jpg");
            byte [] arr = new byte[1024*1024];
            int temp;
            while((temp = input.read(arr)) != -1){
                out.write(arr,0,temp);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(input != null){
                    input.close();
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
  • 字节流复制文件夹
// 文件夹的复制
    @Test
    public void test23(){
        try {
            copyFile(new File("D:\\线下"),new File("G:\\线下"));
            System.out.println("成功");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void copyFile(File file,File fileNew) throws IOException {
        fileNew.mkdirs();
        if(file != null){
            File[] files = file.listFiles();
            if(files != null){
                for (File file1 : files) {
                    if(file1.isFile()){
                            InputStream inputStream = new FileInputStream(file1);
                            OutputStream outputStream = new FileOutputStream(fileNew.getAbsolutePath()
                                    + "\\" + file1.getName());
                            byte [] bytes = new byte[1024*1024];
                            int len =0;
                            while((len = inputStream.read(bytes)) != -1){
                                outputStream.write(bytes,0,len);
                            }
                            inputStream.close();
                            outputStream.close();

                    }else {
                        copyFile(file1,new File(fileNew.getAbsolutePath()
                                + "\\" + file1.getName()));
                    }
                }
            }
        }
  • 构造中可以设置是否追加
  • \nLinux上的换行
  • \r\nwin上的换行
  • \rMac上的换行

字符流

  • 字符输入流:Read,以字符为单位的输入流

  • 字符输出流:Write、以字符为单位的输出流

  • 能够用字符表示的。一般都是文本文件文本数据。相比字节速度更快

	@Test
    public void test12() {
        Reader reader = null;
        Writer writer = null;
        try {
            reader = new FileReader("F:\\cde.txt");
            writer = new FileWriter("F:\\def.txt");
            char[] arr = new char[3];
            int len;
            while ((len=reader.read(arr))!=-1) {
                writer.write(arr,0,len);
            }
            int read = reader.read();
            System.out.println(read);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

字符流复制文件

//字符复制文本文件
    @Test
    public void test06(){
        Reader reader = null;
        Writer writer = null;
        try {
            reader = new FileReader("F:\\一故事一设计模式-LieBrother(完整版).pdf");
            writer = new FileWriter("G:\\设计模式.pdf");
            char [] chars = new char[10];
            int temp;
            while((temp = reader.read(chars)) != -1){
                writer.write(chars,0,temp);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                reader.close();
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
字节流与字符流的不同
  • 字节流任意数据都可以,字符流只能操作文本类型
  • 默认的读取或者写入字节流是一个字节,字符流一个字符
  • 手动给一个数组缓冲。字节流接受的是字节数组,字符流接受的字符数组或者字符串
  • 字节数组一般不需要手动刷新,字符流,一般都是要刷新的,关闭流的时候都会自动刷新
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值