IO流概述和简单使用

  • IO流的作用是实现内存(Java程序)和硬盘之间的数据交互
  • 我们以内存为参照物
    • I 表示intput ,是数据从硬盘进内存的过程,称之为读数据
    • O 表示output ,是数据从内存到硬盘的过程。称之为写数据
  • IO的分类
    • 按流向分类
      在这里插入图片描述

    • 按类型分类
      在这里插入图片描述


字节流写数据入门

	1创建字节输出流对象
		注意事项:        
			如果文件不存在,就创建     
			如果文件存在就清空
	
	2写数据
		注意事项:        
			写出的整数,实际写出的是整数在码表上对应的字符
	
	3释放资源
		注意事项:        
			每次使用完流必须要释放资源
public class Test3 {
    public static void main(String[] args) throws IOException {
        // 创建字节输出流对象
        /*如果字节输出流指向的对象不存在,会自动创建一个空的文件
        如果字节输出流指向的文件存在,会将原文件中的内容清空   */
        FileOutputStream fos = new FileOutputStream("day10\\x.txt");
        // 写入数据
        fos.write(97);
        fos.write(98);
        fos.write(99);
        // 释放资源
        fos.close();
        
        /*x.txt内容:abc*/
    }
}
  • 字节流写数据的3种方式
void write​(int b) // 一次写一个字节数据,得益于隐式数据转换,int可以接受byte和char类型的数据
void write​(byte[] b) // 一次写一个字节数组数据
void write​(byte[] b, int off, int len) // 一次写一个字节数组的部分数据
public class Test02 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("day10\\x.txt");

        /*
        fos.write(65);
        fos.write(66);
        fos.write('c');
        // ABc
        */

        /*
        fos.write("nihaoahiahiahia".getBytes());
        // nihaoahiahiahia
        */
        
        fos.write("ahaha".getBytes(), 1, 3); // hah
        fos.close();
    }
}
  • 字节流写数据的换行和追加写入

      写完数据后,加换行符 
      	windows : \r\n 
      	linux : \n 
      	mac : \r
      	
      字节流写数据如何实现追加写入呢? 
      	public FileOutputStream​(String name,boolean append)
      	创建文件输出流以指定的名称写入文件
      	如果第二个参数为true, 不会清空文件里面的内容
    
public class Test03 {
    public static void main(String[] args) throws IOException {
        // 不会清空原来文件中的内容,而是在其基础上进行追加
        FileOutputStream fos = new FileOutputStream("day10\\x.txt", true);

        for (int i = 0; i < 10; i++) {
            fos.write("hello".getBytes());
            fos.write("\r\n".getBytes()); // windows下的换行
        }
        fos.close();
    }

字节流读数据入门

	1创建字节输入流对象
		注意事项:        
			如果文件不存在,就直接报错
	
	2读数据
		注意事项:        
			读出来的是文件中数据的码表值 a->97
	
	3释放资源
		注意事项:        
			每次使用完流必须要释放资源
public class Test04 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("day10\\x.txt");

        int by;
        while ((by = fis.read()) != -1) {
            System.out.print((char)by);
        }
        fis.close();
    }
}
  • 复制文件案例
public class Test05 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("C:\\Users\\11946\\Desktop\\idea快捷键.jpg");
        FileOutputStream fos = new FileOutputStream("day10\\new.jpg");

        int by;
        while ((by = fis.read()) != -1) {
            fos.write(by);
        }

        fis.close();
        fos.close();
    }
}

IO资源的处理

JDK7版本异常的捕获处理
  • JDK7版本对流的释放做了优化 . 可以使用 try-with-resource 语句 , 该语句确保了每个资源在语句结束时自动关闭。简单理解 : 使用此语句,会自动释放资源 , 不需要自己在写finally代码块了
public class Test01 {
    public static void main(String[] args) {
        /*
        try (创建流对象语句1 ; 创建流对象语句2 ...) {
            // 读写数据
        } catch (IOException e) {
            处理异常的代码...
        }
         */
        try (FileInputStream fis1 = new FileInputStream("day10\\a.txt");
             FileInputStream fis2 = new FileInputStream("day10\\b.txt")) {
            // 读写数据
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 使用try-with-resource , 需要把流对象放在try的小括号中 , 流资源在使用完毕 , 会自动释放资源 , 代码相对于做了简化

字节输入流-读字节数组

  • 为了解决速度问题,把字节流的数据读取字节数组中,提高读取效率
  • 一次读一个字节数组的方法:
    • public int read​(byte[] b):从输入流读取最多b.length个字节的数据
    • 返回的是真实读到的数据个数
public class Test09 {
    public static void main(String[] args) {
        try(FileInputStream fis = new FileInputStream("day10\\a.txt");) {
            byte[] byts = new byte[1024]; // 数组的大小一般为1024的倍数
            int len = -1; // 一次读取的字节个数
            while((len = fis.read(byts)) != -1) {
                System.out.print(new String(byts, 0, len)); // 读取了多少个就用多少个,防止用到没被覆盖的数据
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

字节缓冲流

  • BufferedOutputStream:缓冲输出流
  • BufferedInputStream:缓冲输入流

构造方法:

  • 字节缓冲输出流:BufferedOutputStream​(OutputStream out)
  • 字节缓冲输入流:BufferedInputStream​(InputStream in)

为什么构造方法需要的是字节流,而不是具体的文件或者路径呢?

  • 字节缓冲流仅仅提供缓冲区,而真正的读写数据还得依靠基本的字节流对象进行操作
public class homework03 {
    public static void main(String[] args) {
        File f1 = new File("F:\\img1");
        File f2 = new File("F:\\img2");
        copy(f1, f2);
    }

    // 将f1文件中的内容复制到f2文件中
    private static void copy(File f1, File f2) {
        File[] files = f1.listFiles();
        String path = f2.getPath(); // 文件夹2的路径
        for (File f : files) {
            File newFile = new File(path + "\\" + f.getName());
            try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f));
                 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile));) {
                int len = -1;
                byte[] bys = new byte[1024];
                while((len = bis.read(bys)) != -1) {
                    bos.write(bys, 0, len);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

Properties

Properties概述:

  • 是一个Map体系的集合类
  • Properties中有跟IO相关的方法
  • 不需要加泛型, 默认存储的是Object类型, 但是工作中只存字符串
public class PropertiesDemo01 {
    public static void main(String[] args) {
        // 1 创建集合对象
        Properties properties = new Properties();

        // 2 添加数据
        properties.put("it001", "张三");
        properties.put("it002", "李四");
        properties.put("it003", "王五");

        // 3 遍历集合
        Set<Object> keys = properties.keySet();
        for (Object key : keys) {
            System.out.println(key + " : " + properties.get(key));
        }
    }
}

因为在工作中使用Properties集合主要用来存储字符串, 因此其关于字符串的三个方法我们必须了解

// Object setProperty​(String key, String value) 设置集合的键和值,都是String类型,相当于put方法
// String getProperty​(String key) 使用此属性列表中指定的键搜索属性,相当于get方法
// Set<String> stringPropertyNames​() 从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串 , 相当于keyset方法
public class PropertiesDemo02 {
    public static void main(String[] args) {
        // 1 创建集合对象
        Properties properties = new Properties();

        // 2 添加数据
        properties.setProperty("it001", "张三");
        properties.setProperty("it002", "李四");
        properties.setProperty("it003", "王五");

        // 3 遍历集合
        Set<String> keys = properties.stringPropertyNames();
        for (String key : keys) {
            System.out.println(key + " : " + properties.getProperty(key));
        }
    }
}

Properties和IO流结合的方法:

// void load​(InputStream inStream) 以字节流形式 , 把文件中的键值对, 读取到集合中
// void load​(Reader reader) 以字符流形式 , 把文件中的键值对, 读取到集合中
// void store​(OutputStream out, String comments) 把集合中的键值对,以字节流形式写入文件中 , 参数二为注释, 可以传入null代表不写注释
// void store​(Writer writer, String comments) 把集合中的键值对,以字符流形式写入文件中 , 参数二为注释
// load读取
public class PropertiesDemo03 {
    public static void main(String[] args) throws IOException {
        // 1 创建集合对象
        Properties properties = new Properties();

        // load 读取 properties文件中的信息
        properties.load(new BufferedInputStream(new FileInputStream("day10\\test.properties")));

        System.out.println(properties);
    }
}
// store写入
public class PropertiesDemo04 {
    public static void main(String[] args) throws IOException {
        Properties properties = new Properties();

        properties.setProperty("it001", "zhangsan");
        properties.setProperty("it002", "lisi");
        properties.setProperty("it003", "wangwu");

        properties.store(new BufferedOutputStream(new FileOutputStream("day10\\test.properties")), null);
    }
}

ResourceBundle工具类

API介绍

  • java.util.ResourceBundle它是一个抽象类
  • 我们可以使用它的子类PropertyResourceBundle来读取以.properties结尾的配置文件
  • 通过静态方法直接获取对象
    • static ResourceBundle getBundle(String baseName) 可以根据名字直接获取默认语言环境下的属性资源
    • 参数注意: baseName
      • 1.属性集名称不含扩展名
      • 2.属性集文件是在src目录中的
public class ResourceBundleDemo {
    public static void main(String[] args) {
        ResourceBundle bundle = ResourceBundle.getBundle("user"); // 获取src目录下的user.properties中的内容

        String username = bundle.getString("username"); // 通过键值获取内容
        System.out.println(username);

        // 链式编程
        System.out.println(ResourceBundle.getBundle("user").getString("password"));
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值