当前位置: 首页 > article >正文

JavaSE——IO流(下)

一、节点流与处理流

节点流:也称为低级流,直接与数据源(如文件、网络等)相连,负责数据的实际读写操作。它们是IO操作的基础。

特点

  • 直接性:节点流直接与数据源相连,因此能够直接访问和操作数据。
  • 高效性:由于直接访问数据源,节点流在数据传输时通常具有较高的效率。
  • 基础功能:节点流提供了数据读写的基本功能,是IO操作的基础。

处理流:也成为高级流或者包装流,在节点流的基础上进行加工或者拓展。不直接与数据源相连,而是将节点流包装起来,为节点流提供额外的功能或者优化。

特点:

  • 功能扩展:处理流为节点流提供了额外的功能,如缓冲、加密、解密、压缩、解压缩等。
  • 灵活性:通过使用不同的处理流,我们可以轻松地实现不同的IO功能,而无需修改底层的节点流。
  • 易用性:处理流通常具有更友好的API和更简单的使用方法,使得IO操作更加容易。

二、处理流BufferedReader和BufferedWriter

2.1BufferedReader

BufferedReader bfr = new BufferedReader(new NodeReader(PathName));
bfr.readLine();
bfr.close();

        readLine方法按行读取文件,当返回null时表示文件读取完毕。 最后关闭流时,只需要关闭外层流,因为底层会自动关闭节点流。

public class BufferedReader_ {
    public static void main(String[] args) throws Exception {
        String filePath = "D:\\news.txt";
        //创建bufferedReader
        BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
        //读取
        String line; //按行读取, 效率高
        //说明
        //1. bufferedReader.readLine() 是按行读取文件
        //2. 当返回null 时,表示文件读取完毕
        while ((line = bufferedReader.readLine()) != null) {
            System.out.println(line);
        }

        //关闭流, 这里注意,只需要关闭 BufferedReader ,因为底层会自动的去关闭 节点流
        bufferedReader.close();

    }
}

2.2BufferedWriter 

new FileWriter(filePath) //表示覆盖方式写入
new FileWriter(filePath,true) //表示追加方式写入
newLine() //表示插入一个和系统有关的换行
public class BufferedWriter_ {
    public static void main(String[] args) throws IOException {
        String PathName = "D:\\news.txt";
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(PathName,true));
        bufferedWriter.write("hello1" + "哔哩哔哩动画");
        bufferedWriter.newLine();
        bufferedWriter.write("hello2" + "哔哩哔哩动画");
        bufferedWriter.newLine();
        bufferedWriter.write("hello3" + "哔哩哔哩动画");
        bufferedWriter.close();
    }
}

三、处理流BufferedInputStream和BufferedOutputStream 

        BufferedOutputStream是字节流,实现缓冲的输出流,可以将多个字节写入底层输出流,而不必对每个字节写入调用底层系统。

String srcFilePath = "e:\\a.java";
String destFilePath = "e:\\a3.java";

//创建BufferedInputStream对象
BufferedInputStream bis = null;
//创建BufferedOutputStream对象
BufferedOutputStream bos = null;

try {
    //因为 FileInputStream  是 InputStream 子类
    bis = new BufferedInputStream(new FileInputStream(srcFilePath));
    bos = new BufferedOutputStream(new FileOutputStream(destFilePath));

    //循环的读取文件,并写入到 destFilePath
    byte[] buff = new byte[1024];
    int readLen = 0;
    //当返回 -1 时,就表示文件读取完毕
    while ((readLen = bis.read(buff)) != -1) {
        bos.write(buff, 0, readLen);
    }

    System.out.println("文件拷贝完毕~~~");

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

    //关闭流 , 关闭外层的处理流即可,底层会去关闭节点流
    try {
        if(bis != null) {
            bis.close();
        }
        if(bos != null) {
            bos.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

四、对象流ObjectInputStream和ObjectOutputStream 

        在开发中我们常常有这样的需求:保存数据的同时保存它的数据类型,比如说int 100,我们不仅要保存100这个数字,而是int 100,能够从文件中直接恢复int 100。

序列化:在保存数据时,保存数据的值和数据类型。

反序列化:恢复数据时,恢复数据的值和类型。

要让某个对象支持序列化机制,必须让它是可序列化的,必须实现以下两个接口之一:

Serializable //标记接口,没有方法
Externalizable //该接口有方法需要实现,因此一般使用Serializable

        对象流提供了对基本类型或对象类型的序列化和反序列化,ObjectOutputStream提供序列化功能,ObjectInputStream体哦那个反序列化功能。

4.1ObjectInputStream

//指定反序列化的文件
String filePath = "e:\\data.dat";

ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));

//读取
//1. 读取(反序列化)的顺序需要和你保存数据(序列化)的顺序一致
//2. 否则会出现异常

System.out.println(ois.readInt());
System.out.println(ois.readBoolean());

System.out.println(ois.readChar());
System.out.println(ois.readDouble());
System.out.println(ois.readUTF());


//dog 的编译类型是 Object , dog 的运行类型是 Dog
Object dog = ois.readObject();
System.out.println("运行类型=" + dog.getClass());
System.out.println("dog信息=" + dog);//底层 Object -> Dog

//这里是特别重要的细节:

//1. 如果我们希望调用Dog的方法, 需要向下转型
//2. 需要我们将Dog类的定义,放在到可以引用的位置
Dog dog2 = (Dog)dog;
System.out.println(dog2.getName()); //旺财..

//关闭流, 关闭外层流即可,底层会关闭 FileInputStream 流
ois.close();

4.2ObjectOutputStream 

//序列化后,保存的文件格式,不是存文本,而是按照他的格式来保存
String filePath = "e:\\data.dat";

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));

//序列化数据到 e:\data.dat
oos.writeInt(100);// int -> Integer (实现了 Serializable)
oos.writeBoolean(true);// boolean -> Boolean (实现了 Serializable)
oos.writeChar('a');// char -> Character (实现了 Serializable)
oos.writeDouble(9.5);// double -> Double (实现了 Serializable)
oos.writeUTF("哔哩哔哩动画");//String
//保存一个dog对象
oos.writeObject(new Dog("旺财", 10, "日本", "白色"));
oos.close();
System.out.println("数据保存完毕(序列化形式)");

4.3注意事项和细节说明 

  1. 读写顺序要求一致。
  2. 要求序列化或者反序列化的对象,需要实现Serializable。
  3. 序列化的类中建议添加SerialVersionUID,以提高版本兼容性。
  4. 序列化对象时,默认将所有属性都进行序列化,但除了static或transient修饰的成员。
  5. 序列化对象时,要求属性的类型也实现Serializable接口。
  6. 序列化具备可继承性,也就是说某类已经实现了序列化,则它的所有子类也默认实现了序列化。

五、标准输入输出流

名称编译类型默认设备
System.in标准输入InuputStream键盘
System.out标准输出OutputStream显示器
//System 类 的 public final static InputStream in = null;
// System.in 编译类型   InputStream
// System.in 运行类型   BufferedInputStream
// 表示的是标准输入 键盘
System.out.println(System.in.getClass());

//老韩解读
//1. System.out public final static PrintStream out = null;
//2. 编译类型 PrintStream
//3. 运行类型 PrintStream
//4. 表示标准输出 显示器
System.out.println(System.out.getClass());

System.out.println("hello, 哔哩哔哩动画~");

Scanner scanner = new Scanner(System.in);
System.out.println("输入内容");
String next = scanner.next();
System.out.println("next=" + next);

六、转换流InputStreamReader和OutputStreamWriter 

  1. InputStreamReader:Reader的子类,可以将InputStream(字节流)包装成Reader(字符流)。
  2. OutputStreamWriter:Writer的子类,可以将OutputStream(字节流)包装成Writer(字符流)。
  3. 在处理纯文本数据时,如果使用字符流效率更高,并且可以有效解决中文问题,所以建议将字节流转换为字符流。
  4. 可以在使用时指定编码格式。

6.1InputStreamReader

String filePath = "e:\\a.txt";
//解读
//1. 把 FileInputStream 转成 InputStreamReader
//2. 指定编码 gbk
//InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), "gbk");
//3. 把 InputStreamReader 传入 BufferedReader
//BufferedReader br = new BufferedReader(isr);

//将2 和 3 合在一起
BufferedReader br = new BufferedReader(new InputStreamReader(
                                            new FileInputStream(filePath), "gbk"));

//4. 读取
String s = br.readLine();
System.out.println("读取内容=" + s);
//5. 关闭外层流
br.close();

6.2OutputStreamWriter

String filePath = "e:\\hsp.txt";
String charSet = "utf-8";
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(filePath), charSet);
osw.write("hi, 韩顺平教育");
osw.close();
System.out.println("按照 " + charSet + " 保存文件成功~");

七、打印流PrintStream和PrintWriter

7.1PrintStream

PrintStream out = System.out;
//在默认情况下,PrintStream 输出数据的位置是 标准输出,即显示器
/*
     public void print(String s) {
        if (s == null) {
            s = "null";
        }
        write(s);
    }

 */
out.print("john, hello");
//因为print底层使用的是write , 所以我们可以直接调用write进行打印/输出
out.write("哔哩哔哩,你好".getBytes());
out.close();

//我们可以去修改打印流输出的位置/设备
//1. 输出修改成到 "e:\\f1.txt"
//2. "hello, 哔哩哔哩~" 就会输出到 e:\f1.txt
//3. public static void setOut(PrintStream out) {
//        checkIO();
//        setOut0(out); // native 方法,修改了out
//   }
System.setOut(new PrintStream("e:\\f1.txt"));
System.out.println("hello,哔哩哔哩~");

7.2PrintWriter 

//PrintWriter printWriter = new PrintWriter(System.out);
PrintWriter printWriter = new PrintWriter(new FileWriter("e:\\f2.txt"));
printWriter.print("hi, 北京你好~~~~");
printWriter.close();//flush + 关闭流, 才会将数据写入到文件..

八、Properties类 

        Properties文件是Java支持的一种配置文件类型(所谓支持是因为Java提供了properties类,来读取properties文件中的信息)。文件中以键值对 "键=值"的形式,存储工程中会多次重复使用的配置信息。随后,在需要用到这些配置信息,通过“Properties”类来读取这些信息,以实现“一次编写,多处调用;需要修改配置文件时,只修改一处即可”的效果。

不采用Properties类读取Properties文件:

//读取mysql.properties 文件,并得到ip, user 和 pwd
BufferedReader br = new BufferedReader(new FileReader("src\\mysql.properties"));
String line = "";
while ((line = br.readLine()) != null) { //循环读取
    String[] split = line.split("=");
    //如果我们要求指定的ip值
    if("ip".equals(split[0])) {
        System.out.println(split[0] + "值是: " + split[1]);
    }
}
br.close();

        传统方法也可以读取Properties文件,但是不方便修改、读取某一特定的键值对。

        Properties类专门用于读写配置文件的集合类,它要求配置文件的格式为:键=值,键值对不需要有空格,值不需要用引号引起来,默认是String类型。

        Properties类读写Properties文件:

//使用Properties 类来读取mysql.properties 文件

//1. 创建Properties 对象
Properties properties = new Properties();
//2. 加载指定配置文件
properties.load(new FileReader("src\\mysql.properties"));
//3. 把k-v显示控制台
properties.list(System.out);
//4. 根据key 获取对应的值
String user = properties.getProperty("user");
String pwd = properties.getProperty("pwd");
System.out.println("用户名=" + user);
System.out.println("密码是=" + pwd);

         Properties类创建并修改某个KeyValue:

Properties properties = new Properties();
properties.setProperty("charset", "utf8");
properties.setProperty("user", "汤姆");//注意保存时,是中文的 unicode码值
properties.setProperty("pwd", "888888");
properties.setProperty("","123");
properties.setProperty("","456");//123被覆盖为456
System.out.println(properties.getProperty(""));
//将k-v 存储文件中即可
properties.store(new FileOutputStream("src\\mysql2.properties"), null);
System.out.println("保存配置文件成功~");
 
 

 

 

 
 

 

 


http://www.kler.cn/a/466472.html

相关文章:

  • 常用的数据结构API概览
  • SQL使用游标
  • 简述Linux的信号处理
  • linux-centos-安装miniconda3
  • HTML——56.表单发送
  • [python3]Excel解析库-XlsxWriter
  • 设置开机自启动的应用
  • leetcode(hot100)3
  • MTK 平台关于WIFI 6E P2P的解说
  • 37. 数组二叉树
  • NanoEdge AI Studio入门
  • React-Router 一站式攻略:从入门到精通,掌握路由搭建与权限管控
  • QT------------其他工具软件和技术
  • pcl源码分析之计算凸包
  • 设计模式之访问者模式:一楼千面 各有玄机
  • 养老院小程序怎么搭建?让老年人老有所养,老有所依!
  • 数据挖掘——关联规则挖掘
  • 如何进一步提高Oracle lgwr的写性能?
  • R机器学习:神经网络算法的理解与实操,实例解析
  • eplan如何导出可跳转的PDF
  • 【Rust练习】26.Package and Crate
  • 深入理解 Java Set 集合:原理、应用与高频面试题解析
  • 图片转三维模型网站(免费),AI建模,一键把图片转三维模型,二维图片转3维模型,AI建模
  • 用python编写一个放烟花的小程序
  • 机器学习笔记——正则化
  • Entity Framework Core介绍