模拟BufferedInputStream,编写一个类

package toto.IO;

import java.io.IOException;

import java.io.InputStream;

class MyBufferedInputStream{

private InputStream
in;

private
byte[]
buf =
new
byte[1024*4];

private
int
pos = 0,count
= 0;

MyBufferedInputStream(InputStream in){

this.in
= in;

}

//从缓冲区中读取一个字节

/**

*缓冲区的原理:

*其实就是定义了一个临时容器

*然后将获取到的数据都存入到临时容器中,通过临时容器的方法获取数据,当临时容器

*中的数据取完后,再获取一批数据进容器、

发现自定义的缓冲区出现了秒杀效果

为什么秒杀呢?

的情况。而连续的过程中,出现-1,程序就认为读到了末尾,程序停止读取。

为了避免这种情况,将获取的一个字节数据,进行提升,变成int ,并在保留原有八位的基础上补零。补完后,就变成了正数,就避免了-1的这种情况。

*/

public
int myRead()
throws IOException{

if(count
== 0){

count =
in.read(buf);//通过流对象从硬盘获取一批数据装入缓冲去

pos = 0;//开始取

byte b =
buf[pos];//将数据存入数组

pos++;//取完之后pos++

count--;//取走一个减少一个

return
b&oxff;  
//。这里进行了自动提升效果。

}else
if(count>0){

//第二次取时count>0

byte b =
buf[pos];

pos++;

count--;

return b;

}else {

return -1;

}

}

public
void myClose()throws
IOException{

in.close();

}

}

public
class Demo1 {

}

/*package toto.IO;

import java.io.IOException;

import java.io.Reader;

*//**

*
按照装饰设计模式的思想

*
自定义MyBufferedReader类

*
一样提供一个和BufferedReader功能相同的readLine方法。

*//*

class MyBufferedReader{//extends Reader{

由于它里面中提供Reader中的所有方法,故它要继承Reader类。这里继承的原因是里面的方法太多这里不写了

private FileReader r;这种方式只能包装FileReader类,

要想包装所有的Reader的子类,我们写成以下方式:

private Reader r;

MyBufferedReader(Reader r) {//这里是被包对象

this.r = r;

}

提供一个一次读一行的方法。

* 1、使用的还是Reader中read()方法,一次读一个。

* 2、将读到一个字符进行临时存储。数组和StringBuilder都可以。

* 这里选用StringBuilder,因为可以省略数组延长部分代码的编写。该Builder中使用就是数组

* 而且可变长度,并且最终变成字符串。

* 3、因为自负有很多需要循环读取。

* 4,读取到的字符进行判断,如果是回车符,那么就将StringBuilder中的存储数据作为字符串返回

public String myReadLine() throws IOException {

StringBuilder sb = new StringBuilder();

int ch = 0;

while((ch==r.read())!=-1) {//使用初进来的read方法,并且要判断不等于-1

if(ch=='\r')//遇到这个转义字符时,不能将这个数据读进去,并且将这个数据向下读一个

continue;

if(ch=='\n')

return sb.toString();

sb.append((char)ch);//如果两个都满足,就将数据向里面转了。

}

return null;

}

public void myClose() throws IOException{

r.close();

}

}

public class MyBufferedReader{

public static void main(String[] args) {

// TODO Auto-generated method stub

}

}

*/

转换流

/*

*
转换流,涉及的对象都在字符流体系中。

* InputStreamReader字节转到字符的桥梁。
把看不懂得转换成为看的懂的。

* OutputStreamWriter:字符转到字节的桥梁。把看得懂的转换成为看不懂的。

*
该类本身是一个字符流,因为它是桥梁,需要把一个指定的字节流传给构造函数。

*
将制定的字节流转成字符流。*/

package toto.IO;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

public
class Demo2 {

public
static
void main(String[] args)throws
IOException {

//readIn();

//    
System.out.println('-'+0);

//    
System.out.println('1'+0);

readLineByKey();

}

/*

* 读取键盘录入,并打入的录入的数据

* 当录入了一行数据后,打印录入的一行数据内容。而其可以不断的进行录入

* 一次打印一行。

*

*1,读取键盘通过System.in完成

*2,需要一次打印一行。那么就需要定义一个临时容器,将读取到自己额进行临时存储。

*当读到回车符的时候就降临时容器中存储的数据一次性打印、*/

public
static
void printLineByKey()
throws Exception{

InputStream in = System.in;

int by = 0;

StringBuilder sb = new StringBuilder();

while((by==in.read())!=-1){//这里有警告,不知道为什么

if(by=='\r')

continue;

if(by=='\n')

System.out.println(sb.toString());

else

sb.append((char)by);

}

}

public
static
void readIn()
throws IOException {

//获取标准的输入流,对应的默认设备就是键盘。

//从键盘获取到的数据都是字节数据。

InputStream in = System.in;

//读取键盘录入的一个字节

//通过循环形式,读取一个字节,打印一个字节

int by = 0;

while((by=in.read())!=-1){

System.out.println(by);

}

}

public
static
void readLineByKey()
throws IOException {

//字节读取流

InputStream in =System.in;

//要想使用readLine方法读取一样,就要建立BufferReader对象

//但是该字符流的缓冲区,在对象在初始化时,

//要将一个字符对象作为参数传递给BufferReader的构造函数

//读取键盘是字节流,如何让字符流的缓冲区所使用呢?,这时就需要将字节流转成字节流

//想要进行字节和字符流的转换,就需要IO包中的转换流

//由于早期只有字节流,只有涉及到字符流之后才涉及到转换,故这个转换体系在字符流中。

//InputStreamReader的前面是字节流,后面是字符流。故通过它转换。

InputStreamReader isr = new InputStreamReader(in);

//因为BufferedReader只能包装字符流。故只需将isr传递进去就行了。

BufferedReader bufr = newBufferedReader(isr);

String line = null;

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

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

break;

}

//System.out.println(line.toUpperCase());

}

bufr.close();

}

}

package toto.IO;

/*流操作的基本规律

*
流操作要明确数据源和数据目的(数据汇)

*

*
在现有程序中,

*
源:键盘

*
目的控制台。

* 1、需求:将一个硬盘上的文件打印在控制台上

* 2、需求:将键盘录入的数据存储到一个文件中。

*

* */

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

public
class TransStreamDemo2 {

public
static
void main(String[] args)
throws IOException {

/*InputStream in = System.in;

InputStreamReader isr = new InputStreamReader(in);

BufferedReader bufr = new BufferedReader(isr);*/

//上面三行可以转换成一行,读取键盘最方便方式,因为键盘录入的都是文本数据。所以一次读一行最方便,先将字节流包装成字符流,再将字符流写入缓冲区,提高效率。

/*BufferedReader bufr = new

BufferedReader(new InputStreamReader(System.in));*/

//硬盘上的文件是字节流,要将它转换成字符流,读取硬盘上的一个文件的方式:

BufferedReader bufr = new

BufferedReader(new InputStreamReader(new
FileInputStream("文件地址")));

/*向控制台上输出,使用System.out

OutputStream out = System.out;

OutputStreamWriter osw = new OutputStreamWriter(out);

BufferedWriter bufw = new BufferedWriter(osw);*/

//    
BufferedWriter bufw = new BufferedWriter(newOutputStreamWriter(System.out));

//时,上面是System.in,下面是要写到的文件的路径。当上下都是文件名称时,相当于文件的复制。

BufferedWriter bufw = new BufferedWriter(new
OutputStreamWriter(new FileOutputStream("要写到的文件的地址")));

String line = null;

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

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

break;

}

bufw.write(line.toUpperCase());

bufw.newLine();

bufw.flush();

}

bufw.close();

bufr.close();

}

}

IO包中对象其实都是以围绕读写为主,用于操作数据。

IO技术的难点:因为io包中的对象太多,在实际开发,不太容易明确使用哪个对象

IO操作的基本规律:

1、 作用的数据源和数据目的。

如果是操作数据源:输入流。(InputStream
,Reader),读入的是字节流用InputStream,读入的是字符流用Reader.

如果是操作数据汇:就是输入流。(OutputStream,Writer),输出成字节流用OutputStream,输出成字符用writer

2、 要操作的数据是不是纯文本数据。

如果是:使用字符流

如果不是:使用字节流。

3,根据源和目的的设备来确定要操作的对象。

无论数据源或者数据汇都有存在设备。

源设备:硬盘(File)。键盘(键盘对应的是System.in)。内存(内存对应的都是数组)。

目的设备:硬盘(File),控制台(控制台对应的是:System.out),内存(内存对应的是数组)。

这两个明确可以确定到底要使用上面四个体系中的那个体系。

需求一:对文本文件进行复制

1, 这个需求既有源又有目的

源:硬盘上的文件。InputStream Reader

目的:硬盘上的文件。OutputStream or Writer

是不是纯文本数据呢?是。

源:要使用字符读取流Reader

目的:要使用字符输出流Writer

那么体系确定后,要使用该体系中那个对象呢?

源:是一个文件。所以要使用字符读取流中可以操作文件的对象:FileReader

目的:也是一个文件,所以要使用字符写入流中的可以操作文件的对象:FileWriter

FileReader fr = new FileReader(“a.txt”);

FileWriter fw = new FileWriter(“b.txt”);

该操作过程中是否需要提高侠侣呢?是。

如果是:加入缓冲技术。

代码就变成:

BufferedReader bufr = newBufferedReader(new FileReader(“a.txt”));

BufferedWriter bufw = newBufferedWriter(new FileWriter(“b.txt”));

需求二,将一个硬盘上的文件打印在控制台上。

1, 明确源和目的

源:硬盘的文件。读取文件,体系是InputStream or Reader

目的:控制台。OutputStream or Writer

对于控制台较为特殊,其默认的目的是System.out

2, 是不是纯文本数据

源:Reader

目的Writer

3,明确体系中的对象

源:因为是一个文件,FileReader

目的:因为是控制台对应的对象是System.out,为了便于字符操作,所以将System.out转换成字符流。

FileReader fr =new FileReader(“a.txt”); 
读取字符流

OutputStreamWriterout =new OutputStreamWriter(System.out;); //输出字节流

FileReader fr =new FileReader(“a.txt”); 
读取字符流

OutputStreamWriterosw = new OutputStreamWriter(System.out);这里也变成了字符流了。

char[] buf = new char[1024];

int len = 0;

while((len=fr.read(buf))!=-1){

osw.writer(buf,o.len);  
//将数据写到目的了(buf),即控制体。

}

为了提高效率,加入缓冲技术。

BufferedReader buf = new BufferReader(newFileReader(“a.txt”));

BufferedWriter bufw = newBufferedWriter(new OutputStreamWriter(“b.txt”));

String line = null;

While((lien=bufr.readLine())!=null){

bufw.write(line);

bufw.newLine();

bufw.flush();

}

需求三,将录入的文件写入硬盘上的文件。

1,明确体系;

源:InputStream。    System.in

目的:硬盘文件 
OutputStream,Writer。

2, 明确纯文本。

因为键盘录入的都是字节数据。但是该数据最终得转化成为纯文本。

所以可以使用字符流。

源:Reader

目的:Writer。

3, 明确体系对象

源:因为键盘录入,对应的对象是System.in,是一个字节读取流。

为了可以使用字符读取留来操作这些数据,可以将其转换成字符读取流

目的:因为是一个文本文件,所以可以使用FileWriter。

InputStreamReaderisr = new InputStreamReader(System.in);

FileWriter fw =new FileWriter(“a.txt”);

为了提高效率,加入了缓冲技术

Bufferreader bufr = new BufferedReader(newInputStreamReader(System,in));

BufferedWriter bufw = newBufferedWriter(new FileWriter(“a.txt”));

需求四:读取键盘录入,将录入的信息打印在控制台上,

1体系:

源:InputStream 
Reader

目的:OutputStream,Writer

2纯文本:是

源:Reader

目的:Writer

4, 对象:

源:System.in

目的:System.out

因为键盘录入都是纯文本,所以用字符流操作很方便。

那么就将源和目的都转换成字符流

InputStreamReader isr = newInputStreamReader(System.in);

OutputStreamWriter osw = newOutputStreamWriter(System.out);

需要高效

BufferedReader bufr = newBufferedReader(new InputStreamReaderl(System,in));

BufferedWriter bufw = newBufferedWriter(new OutputStreamWriter(System.out));

注意:在使用写入缓冲区时,记得要进行刷新。flush().

需求五:将一个文本文件中的数据存储到另一个文本文件中,要求按照UTF-8的编码形式存储

1, 体系

源InputStream or Reader

目的:OutputStream or Writer

2,纯文本?yes

源:Reader

目的:Writer

3,对象:

因为操作是文本,而且没有指定编码。所以可以按照默认编码形式

。那么就可以使用FileReader

目的:

按照一般思想,会去找FileWriter。但是FileWriter使用的默认编码。

而需求中要求按照指定编码UTF-8形式存储

那么这时就要用到转换流,因为只有转换流可以在初始化是指定编码。

目的也是一个文件。那么就明确要使用的对象是FileOutStream。

FileReader fr =new FileReader(“a.txt”);

OutlputStreamWriterosw = new OutputStream(new FileOutputStream(“b.txt”),”UTF-8”);

需要提高效率

BufferedReaderbufr = new BufferedReader(new FileReader(a.txt));

BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(newFileOutputStream(“b.txt”),”UTF-8”));

package toto.IO;

import java.io.FileOutputStream;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

import java.io.OutputStreamWriter;

public class TransStreamDemo {

/**

* @param args

*/

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

//writeText();

readText();

}

publicstatic void readAndWrite()throws IOException{

FileReaderfr = new FileReader("test.txt");//字符流

//FileWriterfw = new FileWriter("test1.txt");//默认的字符集。

OutputStreamWriterosw = new OutputStreamWriter(new

FileOutputStream("text1.txt"),"utf-8");//字符流

char[] buf = new char[1024];

intlen = 0;

while((len=fr.read(buf))!=-1){

osw.write(buf,0,len);

}

osw.close();

fr.close();

}

publicstatic void readText() throws IOException{

FileReaderfr = new FileReader("test.txt");//这种编码默认是gbk

intch = fr.read();

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

intch1 = fr.read();

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

fr.close();

}

publicstatic void writeText() throws IOException{

FileWriterfw = new FileWriter("test.txt");

fw.write("你好");

fw.close();

}

}

读取一个UTF-8编码的文件。

BufferedReader bufr =

New BufferedReader(new
FileInputStream(“text.txt”,”utf
-8”)
)

或通过:

InputStreamReaderisr = new InputStreamReader(new FileInputStream(“text.txt”,”utf-8”));

char[] buf = new char[1024];

02_IO操作的基本规律(InputStream,OutputStream,Reader,Writer,FileReader,FileWriter,BufferedReader,BufferedWri的更多相关文章

  1. Java I/O流-总结(InputStream,OutputStream,Reader,Writer)

    Java流总结 一. 流的分类 • 按数据流动方向 – 输入流:只能从中读取字节数据,而不能向其写出数据 – 输出流:只能向其写入字节数据,而不能从中读取数据 • 按照流所处理的数据类型 – 字节流: ...

  2. java13 InputStream,Reader

    流的方向: .输入流:数据源到程序(InputStream,Reader读进来). .输出流:程序到目的地(OutPutStream,Writer写出来). 处理数据单元: 字节流:按照字节读取数据( ...

  3. 字节流InputStream/OutputStream

    字节流InputStream/OutputStream 本篇将对JAVA I/O流中的字节流InputStream/OutputStream做个简单的概括: 总得来说,每个字节流类都有一个对应的用途, ...

  4. InputStream和Reader区别

    InputStream,OutputStream  前者为字节输入流,后者为字节输出流.Reader   Writer  前者为字符输入流,后者为字符输出流. 四个均为抽象类.fileInputStr ...

  5. InputStream和Reader

    java.io下面有两个抽象类:InputStream和ReaderInputStream是表示字节输入流的所有类的超类Reader是用于读取字符流的抽象类InputStream提供的是字节流的读取, ...

  6. Java:IO流(二)——InputStream/OutputStream具体用法:FileXXXStream、ByteArrayXXXStream

    1.说明 InputStream和OutputStream是Java标准库中最基本的IO流,它们都位于java.io包中,该包提供了所有同步IO的功能. 2.模块:java.io.InputStrea ...

  7. InputStream和Reader,FileInputStream和 FileReader的区别

    一.InputStream和Reader的区别 InputStream和Reader都可以用来读数据(从文件中读取数据或从Socket中读取数据),最主要的区别如下: InputStream用来读取二 ...

  8. IO 流(InputStream,OutputStream)

    1. InputStream,OutputStream都是抽象类,所以不能创建对象. 1个中文占两个字节 package com.ic.demo01; import java.io.File; imp ...

  9. Stream,Reader/Writer,Buffered的区别(2)

    Reader: Reader的子类: 1.BufferedReader: FileReader 没有提供读取文本行的功能,BufferedReader能够指定缓冲区大小,包装了read方法高效读取字符 ...

随机推荐

  1. hdu 5266 pog loves szh III(lca + 线段树)

    I - pog loves szh III Time Limit:6000MS     Memory Limit:131072KB     64bit IO Format:%I64d & %I ...

  2. 【NOIP2013】传染病控制

    题目背景 近来,一种新的传染病肆虐全球.蓬莱国也发现了零星感染者,为防止该病在蓬莱国大范围流行,该国政府决定不惜一切代价控制传染病的蔓延.不幸的是,由于人们尚未完全认识这种传染病,难以准确判别病毒携带 ...

  3. 习题 7-3 uva211

    题意:给你28个多米勒牌,要求刚好铺满一个7x8的图,输出所有答 案.每个牌只能使用一次 思路: 对每个位置分别搜索其右边 和 下边. 但是在中途,细节上有点问题.最开始想的是搜到最后一个点输出答案, ...

  4. 动态规划--Kin

    动态规划: 1.最大子序列和 2.LIS最长递增子序列 3.LCS最长公共子序列 4.矩阵连乘 5.数字金字塔 1.最大子序列和 #include<iostream> using name ...

  5. Structured Streaming + Kafka 集成中遇到的问题

    官方指导:http://spark.apache.org/docs/2.2.0/structured-streaming-kafka-integration.html 1.版本问题  起初用的kafk ...

  6. 记录一些移动端H5,小程序视觉还原问题及方法

    前端,特别是移动端如果对视觉还原要求比较高的时候.功能测试和性能测试完成之后.UI真的是一个像素一个像素的给你抠出来哪里还原不到位 之前项目要求还原度要达到98%以上.所以每到视觉还原的时候真的是挺痛 ...

  7. swing JTable 更新数据

    rowData 是将要更新的表格内数据,coloumnName是将要更新的表头数据. table是原本的table对象,更新数据的时候要用 DefaultTableModel 类~ /*更新table ...

  8. Docker 网络

    Docker 的网络实现其实就是利用了 Linux 上的网络名字空间和虚拟网络设备(特别是 veth pair).建议先熟悉了解这两部分的基本概念再阅读本章. 基本原理 首先,要实现网络通信,机器需要 ...

  9. python3.6 使用 pymysql 连接 Mysql 数据库及 简单的增删改查操作

    1.通过 pip 安装 pymysql 进入 cmd  输入  pip install pymysql   回车等待安装完成: 安装完成后出现如图相关信息,表示安装成功. 2.测试连接 import ...

  10. Rails报找不到sanitize和raw方法的解决

    以下一段代码作用是对html字符串做过滤作用: sanitize(raw(content.split.map{ |s| wrap_long_string(s) }.join(' '))) 不过实际会报 ...