文件IO

文件流

IO(input、output)是java重要的核心之一,其中读写操作分为两种:字节流和 字符流

什么是流
流是一个抽象的概念。流式数据很有特点,如我们的自来水一样,未打开水龙头时一滴水都没有,一旦打开,水就源源不断的喷涌而出,直到我们关闭水龙头。
当Java程序需要获取外部的数据时,数据来源可以是文件,内存或者网络等,java就把它们定义为流式数据。同样,当程序需要输出数据到目的地时也一样会开启一个流,数据目的地也可以是文件、内存或者网络等。流的高度抽象后,使我们可以用统一的api来操作文件、内存、网络等,方式统一,代码变的简单。

Java中流分为两种:字节流和字符流,那它们有什么区别呢?
字节流是最基本的,主要用在处理二进制数据,它是按字节来处理的,但实际项目开发中很多的数据是文本类型,于是java又提出了字符流的概念,并且引入Buffer缓存概念,提高读写性能。
简单的说,一般字节流针对二进制文件,字符流针对文本文件。
在这里插入图片描述

1.读写txt文件

文件write

  • 先新建文件流 FileOuputStream() (FOS)
  • 再新建编码转换流OutputStreamWriter (OSW),与文件流相接写文件

读文件read

  1. 先新建文件输入流(FIS) FileInputStream
  2. 再新建转换流(ISR),与文件流相接, InputStreamReader
  3. 再新建BR,与转换流相接BufferedReader
  4. 读取文本文件的经典组合(套餐)
  • BR–ISR–FIS—file
  • FIS: 读取文件
  • ISR: 编码转换
  • BR: 按行读取 readLine()
  • in.close();关闭流
package javase.base.file;
 
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
 
import org.junit.Test;
 
public class TestTxtFile {
    @Test
    public void write() throws IOException {
       File file = new File("d:/javase.txt");
       BufferedWriter bw =
              new BufferedWriter(
                     new OutputStreamWriter(
                            new FileOutputStream(file), "utf-8"));
      
       String msg = "java培优班,实现你高薪就业梦想!";
       try {
           bw.write(msg);
       } catch (IOException e) {
           e.printStackTrace();
       } finally {
           bw.close();
       }
    }
   
    @Test
    public void read() throws IOException{
       File file = new File("d:/javase.txt");
       BufferedReader br =
              new BufferedReader(
                     new InputStreamReader(
                            new FileInputStream(file), "utf-8"));
      
       String line = "";
       while((line = br.readLine()) != null) {
           System.out.println( line );
       }
      
       br.close();
    }
}

读写属性文件jdbc.properties

1.写文件

  • jdbc.properties文件
    properties文件一般用来作为程序的配置文件,例如,连接数据库时,需要知道数据库服务器的地址,用户名,密码等…
    这些连接信息,可以存储在properties配置文件中,便于修改维护java提供了专门的工具,来读写这种格式的数据
    java.util.Properteis 类, 继承 HashTable,本质是一个哈希表,提供了线程的文件读写方法: load(), store(),HashTable是旧版本的哈希表,现在已经废弃,用HashMap代替. 它是线程安全的,安全效率低
    2.读文件
  • 得到Test3.class类文件的存放目录路径Test3.class.getResource("/").getPath()
  • “jdbc.properties”;
  • ISR–FIS–path, 需要用转换流,把UTF-8转成Unicode
package test.file;
import java.io.FileInputStream;
import java.util.Properties;
import org.junit.jupiter.api.Test;
//属性文件操作
public class PropertiesFile {
    @Test  //读取文件
    public void load() throws Exception {
       /*
        * 开发步骤:
        * 1、获取当前类所在的目录
        * 2、创建属性对象Properties
        * 3、读取当前类根目录下的资源目录下的属性文件
        * 4、读取属性文件内容
        * 5、关闭流
        * 6、打印全部内容
        * 7、获取单个属性
        */
      
       //获取当前类所在目录
       String dir = PropertiesFile.class.getResource("/").getPath();
       Properties prop = new Properties();  //创建属性文件对象
       //创建输入文件流对象
       FileInputStream is = new FileInputStream( dir + "/resources/jdbc.properties");
       prop.load(is);    //调用load方法进行文件内容的读取
       is.close();              //流必须关闭
       System.out.println(prop);
       //读取某个值
       String s = prop.getProperty("jdbc.username");
       System.out.println(s);
    }
 }

读取结果:

{jdbc.url=jdbc:mysql://127.0.0.1:3306/yhmisdb?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true, phone=10086, jdbc.username=root, jdbc.driver=com.mysql.jdbc.Driver, jdbc.password=root}
root

解析xml文件

1.用DOM4J解析xml
2.模拟Mybatis框架解析XML

  • *) 如何读取xml文件
  • Document doc = new SAXReader().read(文件);
  • *) 如何获取xml的根元素(顶层元素)
  • Element root = doc.getRootElement();
  • *) 如何从一个元素来获取它的下层元素
  • List list = root.elements(“bean”);
  • *) 如何从一个元素获取它的属性数据
  • List list = e.attributes();
  • *) 如何获得元素内包含的文本
  • String s = e.getText();
  • *) 获取下层元素
  • e.elements()
  • e.element(“元素名”)
  • *) 获取下层元素内的文本
  • e.elementText(“元素名”)
  • *) 直接获取属性的值
  • e.attributeValue(“id”)
    简单点,好做练习
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.yhmis.mapper.OrderMapper">
    <!-- 查询所有 -->
    <select id="list" resultType="Order">
       SELECT * FROM tb_order
    </select>
   
    <!-- 删除某条记录 -->
    <delete id="delete" parameterType="int">
       DELETE FROM tb_order WHERE id=#{id}
    </delete>
</mapper>

解析要求:
根据传入的namespace.id找到对应的标签,然后解析出其SQL语句

package a01;
 
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
 
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
 
public class Test5MybatisXml {
    private static Map<String, String> map = new HashMap<String, String>();
   
    public void configuration() throws Exception {
       String path = getClass().getResource("/OrderMapper.xml").getPath();
       //读取解析xml文件,再获得xml的根元素,即<mapper>元素
       Element root = new SAXReader().read(path).getRootElement();
       //获得namespace属性的值
       String ns = root.attributeValue("namespace");
      
       //获取根元素下一层的所有元素列表
       List<Element> elements = root.elements();
       //遍历元素列表
       for (Element e : elements) {
           String name = e.getName();//元素名称
           String id = e.attributeValue("id");//id属性的值
           String sql = e.getText().trim();//内部包含的文本,即sql语句
           map.put(name+":"+ns+"."+id, sql);//数据放入map
       }
    }
   
    public static void main(String[] args) throws Exception {
       Test5MybatisXml t = new Test5MybatisXml();
       t.configuration();
      
       for(Entry<String, String> e:map.entrySet()) {
           String k = e.getKey();
           String v = e.getValue();
           System.out.println(k+"="+v);
       }
    }
}

执行结果:

select:cn.yhmis.mapper.OrderMapper.list=SELECT * FROM tb_order
delete:cn.yhmis.mapper.OrderMapper.delete=DELETE FROM tb_order WHERE id=#{id}

JSON

json对象和java对象互相转换

非阻塞IO(NIO)

传统的 IO 大致可以分为4种类型:

  • InputStream、OutputStream 基于字节操作的 IO
  • Writer、Reader 基于字符操作的 IO
  • File 基于磁盘操作的 IO
  • Socket 基于网络操作的 IO
    java.net 下提供的 Scoket 很多时候人们也把它归为 同步阻塞 IO,因为网络通讯同样是 IO 行为。

阻塞IO(BIO)

BIO读取过程:共三次复制拷贝过程

  1. jvm堆执行fileInputStream.read()请求操作系统,然后操作系统请求磁盘。
  2. 从磁盘中读取到数据,然后写到操作系统缓冲区中。
  3. 将数据从操作系统缓冲区放到jvm进程缓冲区(按字节流读取,即一个一个字节byte读取数据)。
  4. jvm将jvm进程中缓冲区东西拷贝到jvm堆内存中(应用部署位置)。
    在这里插入图片描述

BIO、NIO、AIO的区别

NIO非阻塞IO与BIO的区别有如下两点

1.相对于bio的一个一个byte传,nio是以channel形式读取buffer缓冲区,然后以块数据传输
在这里插入图片描述
2.nio减少了复制过程
直接把磁盘映射到JVM进程的虚拟地址空间,放置对应到页表上。
在这里插入图片描述
图2,3,4的步骤都没有,取而代之,直接放到jvm的堆中,你说能不快吗?

BIO、NIO、AIO的区别
阻塞IO,BIO 就是传统的 java.io 包,它是基于流模型实现的,交互的方式是同步、阻塞方式,也就是说在读入输入流或者输出流时,在读写动作完成之前,线程会一直阻塞在那里,它们之间的调用时可靠的线性顺序。它的有点就是代码比较简单、直观;缺点就是 IO 的效率和扩展性很低,容易成为应用性能瓶颈。
非阻塞IO,NIO 是 Java 1.4 引入的 java.nio 包,提供了 Channel、Selector、Buffer 等新的抽象,可以构建多路复用的、同步非阻塞 IO 程序,同时提供了更接近操作系统底层高性能的数据操作方式。
异步IO,AIO 是 Java 1.7 之后引入的包,是 NIO 的升级版本,提供了异步非堵塞的 IO 操作方式,所以人们叫它 AIO(Asynchronous IO),异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。但目前还不够成熟,应用不多。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值