Java中的IO框架流二

1      IO(二)No19

缓冲流:内置了缓冲区,对现有的流对象进行了封装,实现了高效的读写操作并增强了功能

字节缓冲流

BufferedInputStream

BufferedOutputStream

字符缓冲流

BufferedReader

特有方法:readLine():第一行(以换行符为标记,读到换行符代表是一行,不包含换行符)

BufferedWriter

特有方法:newLine():输出一个换行符(根据本地系统相关)

设计模式:

【简单工厂、静态工厂、抽象工厂、单利模式、迭代器模式、观察者模式(接口回调)】

装饰者设计模式:

1.1    处理流

昨天的FileStream系列、FileReader、Writer都是节点流,直接和文件这个节点打交道的。节点流对应的是处理流,它们不直接和文件、网络等终端节点打交道,而是对其他流进行装饰、给其他流添加功能

处理流本身也是InputStream、OutputStream、Reader、Writer的子类,如:

BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter,它们可以给对应的体系中的流进行装饰,添加缓冲功能

1.2    BufferedInputStream

字节输入缓冲流:

FileInputStream fis = newFileInputStream("g:/output.txt");

//创建一个缓冲字节输入流,装饰了参数中的fis文件输入流,给它添加了缓冲功能

BufferedInputStream  bis = new BufferedInputStream(fis);

//读一个字节,但不是直接操作磁盘读,而是从内置的缓存中去读

intn = bis.read();

System.out.println(n);

bis.close();      //关闭bis会自动关闭被装饰着的流

BufferedInputStream bis = new BufferedInputStream(newFileInputStream(

"g:/output.zip"));

intn =0;

while((n=bis.read())!=-1){

//不作任何处理,纯粹为演示效率问题

//效率高,因为不是直接从磁盘上一个个读,而是从缓冲区中一个个读

}

bis.close();//关闭缓存流,里面所装饰着的流也会关闭

BufferedInputStream 带缓冲的字节输入流

构造方法:BufferedInputStream(InputStream is)参数是要进行装饰的另一个字节输入流

方法和InputStream基本一致

int read()从缓冲中读一个字节(缓冲空了话就读信息填充)

close()关闭处理流时,会自动关闭被装饰的流

1.3    BufferedOutputStream

字节输出缓冲流:

//用缓存字节输出流装饰文件输出流,添加缓存功能

BufferedOutputStreambos = new BufferedOutputStream(

newFileOutputStream("g:/output.txt"));

bos.write(97);//将数据写到内置缓存中,这里没有实际写到文件中

bos.flush();  //强制刷缓存,刷到文件中

//关闭缓存流,会先刷缓存(97这时候才写到文件里),所装饰的流也会被自动关闭

bos.close();

BufferedInputStream bis = new BufferedInputStream(newFileInputStream(

"g:/output.zip"));

BufferedOutputStreambos = new BufferedOutputStream(

newFileOutputStream("g:/AAoutput.zip"));

intn =0;

while((n=bis.read())!=-1){

bos.write(n);    //写到目标文件的缓存输出流中去

//                        bos.flush();     //每次都直接操作磁盘,效率极低

}

//               bos.flush();         //手动flush

bos.close();         //自动flush

bis.close();

BufferedOutputStream 带缓冲的字节输出流

构造方法:BufferedOutputStream(OutputStream os)参数是要进行装饰的另一个字节输出流

方法和OutputStream基本一致

write(int b)向缓冲中写一个字节(缓冲满了话就将缓冲中的所有字节数据一下子刷到被装饰的流中)

flush()刷缓存,强制将缓存中的字节数据刷到被装饰得流中

close()在关闭之前会先隐式调用flush,然后再关闭

关闭处理流时,会自动关闭被装饰的流

1.4    BufferedReader

字符缓冲流:

BufferedReader br =new BufferedReader(new FileReader("g:/output.txt"));

//从缓存中读取一个字符并打印

System.out.println((char)br.read());

br.close();

BufferedReader br =new BufferedReader(new FileReader("g:/output.txt"));

String line  = br.readLine();    //读取一行信息,用line指向

System.out.println(line);

//读下一行,打印,也就是第二行

System.out.println(br.readLine());

//读下一行,打印,也就是第三行

System.out.println(br.readLine());

System.out.println(br.readLine());

System.out.println(br.readLine());

//读完返回null;

System.out.println(br.readLine());

br.close();   //关闭处理流及其装饰的流

BufferedReader br =new BufferedReader(new FileReader("g:/output.txt"));

String line = null; //存储每次readLine的结果及判断文件尾部

while (true) {

line =br.readLine();//循环读行并赋给line

if (line == null){//如果到达文件尾部

break; //退出循环

}

System.out.println(line);//打印

}

br.close();//关闭处理流和节点流

//制作一个自动批改器,一题一分,最终打印出试卷的成绩

BufferedReaderreader1 = new BufferedReader(new FileReader("g:/answer.txt"));

BufferedReader reader2 = newBufferedReader(new FileReader("g:/tom.txt"));

int count = 0;

while(true){

String line1 =reader1.readLine();

String line2 =reader2.readLine();

if(line1 == null ||line2 ==null){

break;

}

if(line1.trim().equalsIgnoreCase(line2.trim())){

count ++;

}

}

System.out.println(count);

reader1.close();

reader2.close();

BufferedReader 带缓冲的字符输入流

构造方法:BufferReader(Reader r)参数是要进行装饰的另一个字符输入流

int read()从缓存中读一个字符,读完的话返回-1,没读完就返回读到的那个字符

String readLine()从缓存中读一行,如果没有读完,返回表示的下一行的字符串,如果读完,返回null

1.5    BufferedWriter

BufferedWriter 带缓冲的字符输出流

构造方法:BufferedWriter(Writer w)参数是要进行装饰的另一个字符输出流

write(int c)往缓存中写一个字符(缓冲满了会自动刷出去)

write(String s)将参数字符串拆成一组字符写到缓存中去

newLine()往缓存中写换行符(windows中换行\r\n,linux\n)

flush()把缓存中的字节信息一下子强制刷到所装饰的流中

close()关闭缓冲流及其装饰的流,并隐式flush()

1.6    转换流

在System类中定义了三个静态字段,分别是三个流对象

1)System.err“标准”错误输出流,可将错误数据输出到屏幕(控制台)

2)System.out“标准”输出流,可将数据输出到屏幕(控制台)

3)System.in“标准”输入流,可获取从键盘录入的数据

转换流

从键盘录入数据所用的流是一个系统提供的标准流,而系统提供的标准路都是字节流

如果直接使用字节流来操作字符数据的话,会出现很多问题,需要做很多额外的操作

我们可以通过转换流将字节流转换成字符流,JDK中一共提供了两个转换流

InputStreamReader:是字节流通向字符流的桥梁

OutputStreamWriter:是字符流通向字节流的桥梁

实际上:字符流=字节流+编码表

//系统提供三个标准流不要手动关闭,一旦关闭就使用不来了了。

1.6.1  InputStreamReader

转换流:将字节流转换成字符流,使其能够输入汉字:

FileInputStream fis = newFileInputStream("g:/output.txt");

//使用转换流对其装换

InputStreamReaderisr = new InputStreamReader(fis);

intn=0;

while((n=isr.read())!=-1){

System.out.println((char)n);

}

isr.close();

用转换流指定字符集:

//               FileReaderisr = new FileReader("g:/answer.txt");

FileInputStreamfis = new FileInputStream("g:/answer.txt");

//装换为字符流

InputStreamReaderisr = new InputStreamReader(fis,"GBK");

//用缓冲流装饰装换出来的字符流,添加了缓冲的功能

BufferedReaderbr = new BufferedReader(isr);

Stringline = br.readLine();    //读行

System.out.println(line);       //打印

br.close();

FileOutputStream fos = newFileOutputStream("g:/answer.txt");

Stringstr = "安卓";

byte[]bytes = str.getBytes("utf-8");

for(byte b : bytes) {

System.out.println(b);

fos.write(b);//将两个汉字对应的4个字节写到文件中去

}

fos.close();

FileInputStream fis = newFileInputStream("g:/output.txt");

//用utf-8的形式将字节转换为字符

InputStreamReaderisr = new InputStreamReader(fis,"utf-8");

System.out.print((char)isr.read());

System.out.print((char)isr.read());

isr.close();

//有时候我们获取到的输入流就是字节流,无法改变,如:System.in

//这时,可以使用InputStreamReader转换为字符流

BufferedReaderbr = new BufferedReader(new InputStreamReader(System.in));

Stringline = null;

//从系统输入读取一行

while((line= br.readLine())!=null){

if(line.equals("exit")){

break;

}

System.out.println(line);

}

/***

*

*获取用户键盘录入的小写数据,并将数据变成大写显示在控制台上,

*如果用户输入的是exit,则结束键盘录入

*

*/

public class TransferDemo {

/*

*从键盘录入数据所用的流是一个系统提供的标准流,而系统提供的标准路都是字节流

*如果直接使用字节流来操作字符数据的话,会出现很多问题,需要做很多额外的操作

*我们可以通过转换流将字节流转换成字符流,JDK中一共提供了两个转换流

* InputStreamReader:是字节流通向字符流的桥梁

* OutputStreamWriter:是字符流通向字节流的桥梁

*/

publicstatic void main(String[] args) throws IOException {

//InputStreamReader:是字节流通向字符流的桥梁

BufferedReaderbr = new BufferedReader(new InputStreamReader(System.in));

//OutputStreamWriter:是字符流通向字节流的桥梁

BufferedWriterbw = new BufferedWriter(new OutputStreamWriter(System.out));

Stringline = null;

//从键盘录入一行数据,以换行符为标记

while((line= br.readLine()) != null){

if("exit".equalsIgnoreCase(line)){

break;

}

bw.write(line.toUpperCase());

bw.newLine();

bw.flush();

}

bw.close();

br.close();

}

}

转换流可以用来将字节流转换为字符流

InputStreamReader将字节输入流转换为字符输入流

构造方法:InputStreamReader(InputStream is)参数就是要转换为字符流的字节流,构造方法调用后转换即成功,接下来就可以对构造出来的字符流进行操作

(有另一个重载构造方法,可以在new的时候指定字符集)

1.6.2  OutputStreamWriter

//已经有一个字节输出流,想往里写utf-8格式的中文

FileOutputStream fos= new FileOutputStream("g:/answer.txt");

//用转换流装饰节点流,得到一个字符流,转换过程中使用utf-8编码格式

OutputStreamWriter osw = newOutputStreamWriter(fos,"utf-8");

osw.write('征');//这个字符会先以utf-8格式转换为3个字节,再写到底层的流中

osw.write('程');

osw.close();

OutputStreamWriter将字节数出流转换为字符输出流

构造方法:OutputStreamWriter(OutputStream os)参数就是要转换为字符流的字节流

(可以在双参重载构造方法中指定字符集)

实例:

public class Demo3 {

publicstatic void main(String[] args) throws IOException {

//               test1();

//按照指定的字符写数据

BufferedWriterbw = new BufferedWriter(new OutputStreamWriter(

newFileOutputStream("trans.txt"), "UTF-8"));

bw.write("钱今凡vjdjb12521");

bw.newLine();

bw.write("小强......");

bw.close();

BufferedReaderbr = new BufferedReader(new InputStreamReader(

newFileInputStream("trans.txt"), "UTF-8"));

System.out.println(br.readLine());

System.out.println(br.readLine());

br.close();

}

privatestatic void test1() throws IOException {

/*

* FileReader是InputStreamReader的子类,是一个便捷类 这个类使用了默认的编码和字节缓冲区

*/

/*

* 如果编码不统一会出现乱码情况 FileReader fr = newFileReader("e:\\testabc.txt");

* char[] cbuf = new char[1024]; int len =fr.read(cbuf);

* System.out.println(new String(cbuf, 0,len));

*/

//使用指定的编码来读取指定文本文件中的数据

FileInputStreamfis = new FileInputStream("E:\\testabc.txt");

//将字节流转换为字符流 实际上:字符流 = 字节流 + 字符编码

InputStreamReaderosr = new InputStreamReader(fis, "UTF-8");

char[]cbuf = new char[1024];

intlen = osr.read(cbuf);

System.out.println(newString(cbuf, 0, len));

}

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容

  • 1 IO(三)No20 1.1Properties 属性集 【 Properties属性集,主要用于操作配置属...
    征程_Journey阅读 887评论 0 1
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,581评论 18 399
  • # 3.1 File # ## 3.1.1 File基本概念 ## 1.基本概念 -File类用于表示文件(目录)...
    闫子扬阅读 457评论 0 0
  • 1 IONo18 1.1IO框架 【 IO:Input Output 在程序运行的过程中,可能需要对一些设备进...
    征程_Journey阅读 948评论 0 1
  • 店铺:玛格利塔(金祥店) 1.排班采用三班制控制加班,保证到每个时间段有较充足的人手。这个排班表比较直观看到每个时...
    闲庭漫步的羊阅读 631评论 2 0