天天看点

02_IO操作的基本规律(InputStream,OutputStream,Reader,Writer,FileReader,FileWriter,BufferedReader,BufferedWri



模拟bufferedinputstream,编写一个类

package toto.io;

import java.io.ioexception;

import java.io.inputstream;

private inputstream

in;

private

byte[]

buf =

new

byte[1024*4];

int

pos = 0,count

= 0;

mybufferedinputstream(inputstream in){

this.in

= in;

}

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

/**

*缓冲区的原理:

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

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

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

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

为什么秒杀呢?

因为mp3这样的媒体数据,对应的二进制数据,很有可能出现连续多个1的情况。而连续的过程中,出现-1,程序就认为读到了末尾,程序停止读取。

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

 */

public

int myread()

throws ioexception{

if(count

== 0){

count =

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

pos = 0;//从0开始取

byte b =

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

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

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

return

b&oxff;  

//这里与上的是255。这里进行了自动提升效果。

}else

if(count>0){

//第二次取时count>0

buf[pos];

pos++;

count--;

return b;

}else {

return -1;

void myclose()throws

ioexception{

in.close();

class demo1 {

/*package toto.io;

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:字符转到字节的桥梁。把看得懂的转换成为看不懂的。

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

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

import java.io.bufferedreader;

import java.io.inputstreamreader;

class demo2 {

static

void main(string[] args)throws

ioexception {

//readin();

//    

system.out.println('-'+0);

system.out.println('1'+0);

readlinebykey();

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

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

 * 一次打印一行。

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

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

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

void printlinebykey()

throws exception{

inputstream in = system.in;

int by = 0;

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

if(by=='\r')

if(by=='\n')

system.out.println(sb.tostring());

else

sb.append((char)by);

void readin()

throws ioexception {

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

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

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

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

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

system.out.println(by);

void readlinebykey()

//字节读取流

    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();

/*流操作的基本规律

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

在现有程序中,

源:键盘

目的控制台。

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

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

 * */

import java.io.bufferedwriter;

import java.io.fileinputstream;

import java.io.fileoutputstream;

import java.io.outputstreamwriter;

class transstreamdemo2 {

void main(string[] args)

/*inputstream in = system.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));

//写需求1时,上面包装流中式文件路径,下面是system.out,当写需求2时,上面是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;); //输出字节流

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”));

while((lien=bufr.readline())!=null){

bufw.write(line);

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

1,明确体系;

源:inputstream。    system.in

目的:硬盘文件 

outputstream,writer。

2, 明确纯文本。

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

所以可以使用字符流。

目的: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纯文本:是

目的: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

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”));

import java.io.filereader;

import java.io.filewriter;

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;

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);

publicstatic void writetext() throws ioexception{

filewriterfw = new filewriter("test.txt");

fw.write("你好");

fw.close();

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

bufferedreader bufr =

)

或通过:

inputstreamreaderisr = new inputstreamreader(new fileinputstream(“text.txt”,”utf-8”));

继续阅读