JavaIO基础(2)_IO字符流、IO字节流、对象流

IO概述

计算机的核心(CPU和内存),与其它设备之间数据转移的过程就是IO。比如数据从磁盘读入到内存,或内存的数据写回到磁盘,都是IO操作。在计算机的世界里,这就是IO的本质

IO = Input + Out

最简单的例子,CPU将内存中的数据换出到磁盘,就叫Out,反之,从磁盘将数据换入到内存,叫Input

IO流在java中-以输入输出角度分类

  1. 输入流
  2. 输出流

IO流在java中-以数据形式的角度分类

  1. 字符流
  2. 字节流

字符流以我们平常用的文本文件为代表,字节流以我们平时用的mp3、视频、图片等文件为代表,以二进制文件形式传输

IO流的使用必须关闭

流对象占用了系统资源,比如:文件句柄、端口、数据库连接等。无法简单从JVM堆中自动回收,故使用时需要手动关闭

字符输出流Writer

Writer类是一个抽象类,我们使用它的孙子类FileWriter来做演示,它支持将字符流写出到某个文件中

  • 基本构造器:
        File file = new File("test.txt") ;
        Writer writer = null ;
        try {
            writer = new FileWriter(file) ;
     				//or
            writer = new FileWriter("text1.txt") ;
						//覆盖模式 非追加  
            writer = new FileWriter("text1.txt",true) ;
                
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (writer!= null){
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
  • 写入方式
        try {
            writer = new FileWriter("text1.txt",false) ;

            //字符数组方式写入
            char[] c= {'a','b','c'} ;
            writer.write(c);
            writer.write(c,1,1);//从第几个下标,以几个长度写入

            //字符串形式写入
            writer.write("helloword\r\n"); //\r\n表示换行,如果linux下变成,直接\n即可


           //分批写入
            for (int i = 0 ; i<100 ; i++) {
                writer.write("helloword\r\n");  
                if (i == 100)
                    //将缓冲区数据全部打到输出流
                    writer.flush();
            }

我们一般用第三种方法进行文件字符流写

FileReader字符输入流

 	Reader reader = null ;	 
	reader = new FileReader("text1.txt") ;
	

单字符读取:

   int c = reader.read() ;
   System.out.println(  (char)c  );
  • 单字符读取读的过程像指针,一去不复返
  • 返回值:读到的字符个数
  • 最后读出来是个**-1**代表无内容
  • 效率低下,一般不用

以数组为单位读:

   /*按数组组读取:读入数组*/
    char[] cs = new char[5];
    int len = reader.read(cs) ; //读取到多少个有效数据
    System.out.println(Arrays.toString(cs));
    System.out.println(len);
结果:hello
	 5
  • 若读取后的剩余内容少于数组长度,会覆盖数组前节相应长度的内容
  • 无数据是-1

批量读取:

     char[] cs = new char[5];
     while ((c = reader.read(cs))!=-1){   //= -1即读取完毕            
         String str = new String(cs,0,c) ;//0代表起始位置,c代表读取到的长度
         System.out.println(str);
     }

BufferedReader/BufferedWriter

带着缓冲区的字符读写

  • 一次IO换入换出代表CPU得暂停当前线程,等待数据换入完毕或换出,这个时候如果切换线程则有线程上下文的代价,如果不切换则浪费CPU资源,故IO次数当然是越少越好

基本构造:

BufferedReader br  = null ;
BufferedWriter bw = null ;

 br =  new BufferedReader(reader) ;
 bw = new BufferedWriter(writer) ;

读取数据:

  			String str = null;
				//BufferedReader读结束的标志是返回的是null
  			while ((str = br.readLine()) != null){
                System.out.println(str);
         }

写出数据:

BufferedWriter的写方法是按字符串换出的,如需要换行,在写入方法的后面添加newLine(换行方法)

并且需要分批flush

		   bw.write("hello1");
       bw.newLine(); //换行
       bw.write("hello2");
       //须加个flush
       //上面的输出会被暂时放在缓冲区中
       //flush的时候换出到磁盘文件,减少IO次数
       writer.flush(); 

字节流和字符流的区别

每次读写的字节数不同;

字符流是按块读写,字节流是以字节为单位读写;

字符流带有缓存,字节流没有。

字符流和字节流,一个属性范围小,一个属性范围大,字符流只能是字符这一种类型,但是字节流中可以是字符,可以是二进制文件,可以是音频,可以是各种各样的类型,只要符合字节形式存储的都可以接字节流,而字符流只能接字符

字节IO流对象

 OutputStream out =null ;
 InputStream in  = null ;

    //文件输入流
     in = new FileInputStream("testIO2.txt") ;
		//文件输出流
    out =  new FileOutputStream(new File("testIO2.txt")) ;
    //文件输出流 追加模式
    out1 =  new FileOutputStream("testIO2.txt",false) ;	

写入

一般以数组形式进行写入

	 byte[] bs = {97,99,103,111} ; //展示的是asc码
   out.write(bs);

读取

   byte[] bs1 = new byte[2] ;
   int len = -1 ;//-1代表读不到东西了
   while ((len = in.read(bs1)) != -1){ 
   String str = new String(bs1,0,len) ;        

OutputStreamWriter/InputStreamWriter

OutputStreamWriter是从字符流到字节流的桥接:写入它的字符使用指定的字节编码为字节集

此部分主要考虑编码问题,比如我们需要控制输入与输出的编码,如控制流以GBK编码写入,以GBK编码读取(展示)

  OutputStreamWriter ow = null;
  InputStreamReader ir = null ;
  /*参数为out/inputstream对象*/ 
  ow = new OutputStreamWriter(new FileOutputStream("testIO2.txt"),"utf-8")
  ir = new InputStreamReader(new FileInputStream("testIO2.txt"),"utf-8") ;

对象流

由于jvm的机制,对象在程序运行结束后会被回收,如果我们需要讲对象持久化存储,可以考虑把对象以流的形式存储在硬盘上或者数据库中,这个过程就是序列化流

  • 对象输出流:ObjectOutputStream(将Java 对象的基本数据类型和图形写入 OutputStream)
  • 对象输入流:ObjectInputStream (对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化(提取回来))
  • 被序列化的实体类需实现Serializable接口

Student student = new Student(101,"武松") ;
Student student1 = new Student(102,"刘备") ;

/*多个对象需要以集合的方式序列化*/
 List<Student> sList = new ArrayList<>() ;
 sList.add(student);
 sList.add(student1);

/*对象流创建*/
ObjectOutputStream out = null ;
ObjectInputStream in = null ;
out = new ObjectOutputStream(new FileOutputStream("testIO2.txt")) ;
in = new ObjectInputStream(new FileInputStream("testIO2.txt")) ;

序列化:

out.writeObject(sList); //结果(对象数据)是不支持读懂的,反序列化才行
out.flush(); //对象流需要刷新

反序列化

 Object o = in.readObject();
 List<Student>  lists = (List<Student>)o ;
 System.out.println(lists);
/*结果
*[Student{sno=101, name='武松', books=[]}, Student{sno=102, name='刘备', books=[]}]
*/
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值