IO流

1、File类:代表文本

File是Java包下的类,file类的对象,用于代表当前操作系统的文件,可以是文件、文件夹

  • 获取文件信息(大小,文件名,修改事件)
  • 判断文件类型
  • 创建或删除文件/文件夹

注意:File类只能对文件本身进行操作,不能读写文件里面存储的内容,如果想要读写得使用 io 流。

创建File对象

        // 1.创建一个file对象,指代表某个具体文件
        // 路径分隔符 : \\  /  File.separator
        // File file1 = new File("E:\\myShare\\Hello.txt");
        // File file1 = new File("E:/myShare/Hello.txt");
        File file1 = new File("E:" + File.separator +"myShare"+File.separator+"Hello.txt");
        System.out.println(file1.length()); // 文件大小  13B

        File file2 = new File("E:\\myShare"); // 文件
        System.out.println(file2.length()); // 这里是文件夹本身的大小  13B

        // 路径也可以是不存在的文件,可用于创建文件
        File file3 = new File("E:\\myShare\\a.txt");
        System.out.println(file3.exists()); //false
        
        // 绝对路径:从系统盘符开始写,在其他电脑运行不方便,不推荐
        // 相对路径 ./ 代表当前文件所在目录  ../ 表示当前文件上级目录
        File file4 = new File("./myShare/Hello.txt");
        System.out.println(file4.length()); // 文件大小  13B

判断信息相关的方法

        // 1.创建文件对象,指代某个文件
        File f1 = new File("./hello.txt");
        
        // 2.判断当前文件对象对应的文件路径是否存在,存在返回true
        System.out.println(f1.exists());
        
        // 3.判断当前文件对象所指代是否是文件,是返回true
        System.out.println(f1.isFile());
        
        // 4.判断当前文件对象所指代是否是文件夹,是返回true
        System.out.println(f1.isDirectory());
        
        // 5.获取文件名称,包括后缀
        System.out.println(f1.getName());
        
        // 6.获取文件大小,返回字节个数
        System.out.println(f1.length());
        
        // 7.获取文件最后修改时间
        long time = f1.lastModified();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        System.out.println(sdf.format(time));
        
        // 8.获取文件使用的路径
        System.out.println(f1.getPath());
        
        // 9.获取绝对路径
        System.out.println(f1.getAbsolutePath());

创建,删除文件夹的方法

        // 1.createNewFile() :创建一个新文件,内容为空,成功返回true
        File f1 = new File("./hello.xml");
        if (f1.createNewFile()){
            System.out.println("创建成功");
        } else {
            System.out.println("创建失败");
        }
        // 2.mkdir() :只能创建一级文件夹
        File f2 = new File("./src/resource");
        System.out.println(f2.mkdir());

        // 3.mkdirs() :创建多级文件夹
        File f3 = new File("./src/resource/a/b/c");
        System.out.println(f3.mkdirs());
        
        // 4.delete() :删除文件或者空文件夹,注意,不能删除非空文件夹
        System.out.println(f3.delete());  

遍历文件夹

// 1.String List();获取当前目录下的所有"一级文件名称"到一个字符数组返回
        File f1 = new File("./src");
        String[] names = f1.list();
        for (String name : names) {
            System.out.println(name);
        }

        // 2.File[] listFiles();获取当前目录下的所有"一级文件对象"到一个文件对象数组返回
        File[] files = f1.listFiles();
        for (File file : files) {
            System.out.println(file.getPath());
        }
        
        /*
        * 当主调是文件,返回null
        * 挡主调是空文件夹,返回长度为0的空数组
        * 函数包括隐藏函数
        * 如果主调访问没有权限访问的文件夹,返回null
        */

文件搜索:递归

     /**
     * 去目录dir下搜索文件名为fileName的文件
     * @param dir 目录
     * @param fileName 文件名称
     */
    public static void searchFile(File dir,String fileName){
        // 1.拦截非法情况
        if (dir == null || !dir.exists() || dir.isFile()){
            return;//无法搜索
        }

        // 2.dir为目录对象
        // 获取当前目录下的全部一级文件对象
        File[] files = dir.listFiles();

        // 3.判断当前目录下是否存在一级文件对象,一级是否可以难道一级文件对象
        if (files != null && files.length > 0){
            // 4.遍历全部一级对象
            for (File file : files) {
                // 5.判断文件是否是文件夹还是文件夹
                if (file.isFile()){
                    // 是文件,判断是否要找到
                    if (file.getName().contains(fileName)){
                        System.out.println("找到了" + file.getAbsolutePath());
                        Runtime runtime = Runtime.getRuntime();
                        // 可以启动软件
                        runtime.exec(file.getAbsolutePath());
                    } else {
                        // 是文件夹,重复这个过程(递归)
                        searchFile(file,fileName);
                    }
                }
            }
        }
    }

2、字符集

  • 标准ASCII使用1个字节存储1个字符,首尾是0,总共可表示128个字符。
  • GBK中一个中文字符编码成 2 个字节形式存储,GBK兼容ASCCII字符集
  • GBK规定汉字的第一个字节的第一位必须是1
1XXXXXXX XXXXXXXX 0XXXXXXX 1XXXXXXX XXXXX

一2三

Unicode

UTF-32 : 4个字节表示一个字符,占空间,通信效率低

UTF--8 : 采取可边长编码方案,共四个长度区: 1个字节,2个字节,3个字节,4个字节

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

注意:

字符编码时使用的字符集和解码所用字符集必须一致,否则会用乱码问题。

英文、数字不会乱码。

JAVA完成编码、解码

3、IO流:读写数据

  • 用于读写数据(文件或者网络中的数据)
  • I : input 输入流 ,负责把数据读到内存去
  • O : output 输出流,负责写文件出去,例如:网络、硬盘等

分类

IO流的体系

 

4、字节流

字节输入流

        InputStream is = new FileInputStream("./hello.txt");
        /* read()注意
         * 一次只读取一个字节,读取到最后一个数据返回-1
         * 效率差。需要调用系统资源,文件大对系统开销大
         * 汉字中会存在乱码问题
         */
        int b;// 记录当前读取的字符
        while ((b = is.read()) != -1){
            System.out.print((char)b);
        }
        // 流使用完毕必须关闭
        is.close();
        InputStream is = new FileInputStream("./hello.txt");
        byte[] buffer = new byte[8];
        int len;// 记录当前读取的字节数
        while ((len = is.read(buffer)) != -1){
            // 读多少,就倒出多少
        // 输出汉字还是可能会乱码 System.out.println(new String(buffer,0,len)); } // 流使用完毕必须关闭 is.close();

解决字节乱码:一次读取完全部的字节,字节数组和文件大小一样大。可能会引起内存溢出

字节流更适合做数据的转移,如文件复制等

字节输出流

 注意:

  • 中文输出会有乱码问题
  • 换行符写法:”\r\n“.getBytes()

 释放资源的方案

try {
    ....    
} catch (IOException e) {
    e.printStackTrace();     
} finally {

}
// 该资源使用完毕后,会自动关闭资源,完成资源的释放
// 资源一般指的是最终实现AutoCloseable接口
try(定义资源1;定义资源2;...) { 可能出现的异常代码; } catch (异常类名 变量名) { 异常处理的代码; }

文件字符输入流

 

try(
                // 创建一个文件字符流官道与源文件联通
                Reader r = new FileReader("./hello.txt");
                ){
            // 记录文本文件的内容
            int c;
            // 每次读取一个字符
//            while ((c = r.read())!= -1){
//                System.out.print((char)c);
//            }
            // 每次读取多个字符
            char[] buffer = new char[3];
            int len;
            while((len = r.read(buffer))!= -1){
                System.out.print(new String(buffer,0,len));
            }
        } catch (Exception e){
            e.printStackTrace();
        }

文件字符输出流

 注意:

  • 字符输出流写出数据后,必须刷新流,或者关闭流,写出的数据才算数。
  • 当创建文件字符输出流,会创建缓冲区,等数据都在缓冲区,在使用系统调用写到文件中。
  • 刷新后,流可以进行使用,关闭后不可用,但包含刷新操作。

缓冲流

字节缓冲流

字符缓冲输入流

字符缓冲输出流

转换流

  • 当代码编码和被读取的文本文件的编码不一样,使用字符流读取或写入的文本文件就会出现乱码!
  • 可以用来把字节流转换为字符流

字符输入转换流

字符输出转换流

 打印流

内部包装了缓冲流,比较高效。

支持写字节

支持写字符

 打印流应用:输出语句的重定向

可以把输出语句的打印位置改到某个文件去。

PrintStream ps = new PrintStream("文件地址");
// 把系统默认的打印流对象改成自己设置的
System.setOut(ps);

数据流

数据输出流

数据输入流

 序列化流

  • 对象序列化:把Java对象写入到文件中去。
  • 对象反序列化:把文件的Java对象读出来。
  • 对象如果要参与序列化,必须实现序列化接口 : Serializable 。
  • 如果想要对象中某个成员,可以加一个 transient 修饰。
  • 如果一次序列化多个对象,可以用ArrayList集合存储多个对象,在对集合进行序列化。

对象字节输出流

 对象字节输入流

 

posted @ 2023-06-24 00:32  颜欢兮  阅读(17)  评论(0)    收藏  举报