「Java基础」IO流-2

本文深入讲解了Java中IO流的概念及应用,包括字符流和字节流的分类,自定义缓冲区实现,以及如何将字节流转换为字符流进行编码处理。探讨了流操作的基本规律,展示了如何通过不同流对象读写文件、处理设备输入和输出。

IO流-2

IO操作流对象,分为对字符流和字节流的操作,直白点就是字符流操作纯文本对象,字节流操作非纯文本对象,例如图片,音乐,等多媒体文件。

字符流类:
FileReader
FileWriter

BufferedReader 附带缓冲区
BufferedWriter

字节流类:
FileInputStream
FileOutputStream

BufferedInputStream 附带缓冲区
BufferedOutputStream

1 自定义缓冲区

import java.io.IOException;
import java.io.InputStream;

public class MyBufferedInputStream {
    private InputStream in;
    private byte[] buf = new byte[1024];
    private int pos=0,count=0;
    MyBufferedInputStream(InputStream in)
    {
        this.in = in;
    }
    public int myRead() throws IOException //问题1:为什么读入使用byte,而返回值为int
    {
        if(count==0)
        {
            count = in.read(buf);// 字节流read方法读取时,会将byte读为int,
            if(count<0)
                return -1;
            pos = 0;
            byte b = buf[pos];
            count--;
            pos++;
            return b&255;// 问题2:b与255?
        }
        else if(count>0)
        {
            byte b =buf[pos];
            count--;
            pos++;
            return b&255;
        }
        return -1;
    }
    public void myClose() throws IOException
    {
        in.close();
    }
}
// 主程序
import java.io.*;

public class CopyPic {
    public static void main(String[] args) throws IOException
    {
        long start = System.currentTimeMillis();
        copy_3();
        long end = System.currentTimeMillis();
        System.out.println((end-start)+"毫秒");

    }
    public static void copy_3() throws IOException
    {   // 新建缓冲区,文件读入缓冲区。
        MyBufferedInputStream bufis = new MyBufferedInputStream(new FileInputStream("PIG.jpg"));
        BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("PIG_copy2.jpg"));
        int by = 0;
        System.out.println(bufis.myRead()); // 读出来了一个-1,表示说明读到了8个1,为了解决误判,就需要将byte转为int型
        while ((by=bufis.myRead())!=-1)
        {
            bufos.write(by);
        }
        bufos.close();
        bufis.myClose();
    }
}

问题1.1:为什么读入使用byte,而返回值为int?

回答:
知识的预先铺垫:
1byte = 8字节,1 int = 4byte = 32字节
所以会出现这样一种情况:当读到了1byte,例如读到了1111-1111,byte代表-1的二进制,当提升等级之后int也代表-1,所以在返回-1时表示写入的数据,同时,结束条件判断结果为真,结束写入,所以需要解决错误导致的结束。

问题1.2:使用b&255结束

例如byte读到了11111111,read()方法升级为int型32位, 11111111-11111111-11111111-11111111,在后八位补保持不变的情况下向前补1,得到int型,可是此时还是int型-1,所以需要稍加修改为向前补0,而非补1

 11111111-11111111-11111111-11111111
 00000000-00000000-00000000-11111111  -->10进制中表示为255
 ———————————————————————————————————— &
 00000000-00000000-00000000-11111111

所以将读到的结果与上255可以完成向前补零的这个过程,解决了int型被提升之后仍然返回-1的情况。

问题1.3:既然将byte的8字节文件转换成为了int型32字节文件,那么是不是文件的大小就扩大了4倍呢?

回答:并不是,write()方法在写入数据时,只从最低位写入8位有效数据,所以文件的大小还是保持不变的。

2 字节流转换为字符流

字节流与字符流之间的转换:
InputStreamReader类,这个类的用法是先获得字节流,在使用这个类转化为字符流,此时可以对获得的字节流指定字符级,重新编码,也可以再使用装饰器方法,加入缓存类

InputStream in = System.in;

InputStreamReader isr = new InputStreamReader(in);

BufferedReader bufr = new BufferedReader(isr);

3 设备输入存储到文件

设备:键盘 | 对应:System.in | 对应字节流

需要使用InputStreamReader类进行转换,再加入缓冲区BufferedReader

// 用流来读取数据,转换字符操作串
import java.io.*;

public class TransStreamDemo3 {
    public static void main(String[] args)throws IOException
    {
        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
        // 使用字节流可以转换文本的编码,指定编码类型,将文本文件以字节流对象处理
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8");
        // 是否需要缓冲?
        BufferedWriter bufw = new BufferedWriter(osw);
        String line = null;

        while (((line=bufr.readLine()))!=null)
        {
            if("over".equals(line))
                break;
            bufw.write(line.toUpperCase());
            bufw.write("\r\n");
            bufw.flush();
        }
        bufr.close();

    }
}

4 将文件数据打印到控制台上

输入: 文件字节流读入–>字节流转换字符流–>加入缓冲区
输出: 控制台输出–>字节流写入–>加入缓冲区


import java.io.*;

// read
public class TransStreamDemo {
    public static void main(String[] args) throws IOException
    {
    	// 文件字节流读入-->字节流转换字符流-->加入缓冲区
        BufferedReader bufr = new BufferedReader(new InputStreamReader(new FileInputStream("/Users/zy/zy_Javase/my_work/day19/19/src/ReadIn.java")));
        // 控制台输出-->字节流写入-->加入缓冲区
        BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
        String line = null;
        while ((line=bufr.readLine())!=null)
        {
            if(line.equals("over"))
                break;
            bufw.write(line.toUpperCase());
            bufw.newLine();
            bufw.flush();
        }
        bufr.close();
    }
}

5 流操作的基本规律

1.明确源和目的
源:输入流 InputStream Reader
目的:输出流 OutputStream Writer

2.操作的数据是否为纯文本?
是:字符流
不是:字节流

3.明确需要使用哪个对象之后,通过设备区分对象
源设备:内存(这个没讲)、 硬盘(FileReader | FileStreamReader)、键盘(System.in)
目的设备:内存、硬盘、控制台

6 获取系统信息并保存到文件

import java.util.*;
import java.io.*;
class  SystemInfo
{
	public static void main(String[] args) throws IOException
	{
		Properties prop = System.getProperties();

		//System.out.println(prop);
		prop.list(new PrintStream("sysinfo.txt"));
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值