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

被折叠的 条评论
为什么被折叠?



