您的位置:首页 > 职场人生

黑马程序员——IO流

2015-08-20 22:49 597 查看
——- android培训java培训、期待与您交流! ———-

黑马程序员IO流
IO流常用基类

字符流
字符流创建文件

字符流读取文件

字符流继承体系简图

字符流的缓冲区

装饰设计模式

字节流
字节流继承体系简图

字符流的缓冲区

转换流

IO流的操作规律总结

IO包中的其他类

IO流体系

黑马程序员——IO流

IO流用来处理设备之间的数据传输

Java对数据的操作是通过流的方式

Java用于操作流的对象都在IO包中

流按操作数据分为两种:字节流与字符流。

流按流向分为:输入流,输出流。

IO流常用基类

字节流的抽象基类:

InputStream, OutputStream。

字符流的抽象基类:

Reader, Writer。

注:由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。

如:InputStream的子类FileInputStream。

如:Reader的子类FileReader。

字符流

字符流:为了处理文字数据方便而出现的对象。

其实这些对象的内部使用的还是字节流(因为文字最终也是字节数据)

只不过,通过字节流读取了相对应的字节数,没有对这些字节直接操作。

而是去查了指定的(本机默认的)编码表,获取到了对应的文字。

简单说:字符流就是 : 字节流+编码表。

字符流——创建文件

创建流对象,建立数据存放文件

FileWriter fw = new FileWriter("Test.txt");


调用流对象的写入方法,将数据写入流

fw.write("text");


关闭流资源,并将流中的数据清空到文件中。

fw.close();


代码:

FileWriter fw = null;
try {
fw = new FileWriter("Test.txt");
fw.write("text");
} catch (IOException e) {
System.out.println(e.toString());
} finally {
if (fw != null) {
try{
fw.close();
} catch (IOException e) {
System.out.println(e.toString());
}
}
}


字符流——读取文件

建立一个流对象,将已存在的一个文件加载进流。

FileReader fr = new FileReader("Test.txt");


创建一个临时存放数据的数组。

char[] ch = new char[1024];


调用流对象的读取方法将流中的数据读入到数组中。

fr.read(ch);


代码:

FileReader fr = null;
try {
fr = new FileReader("c:\\test.txt");
char[] buf = new char[1024];
int len = 0;
while ((len = fr.read(buf)) != -1) {
System.out.println(new String(buf, 0, len));
}
} catch (IOException e) {
System.out.println("read-Exception :" + e.toString());
} finally {
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
System.out.println("close-Exception :" + e.toString());
}
}
}


字符流继承体系简图



字符流的缓冲区

缓冲区的出现提高了对数据的读写效率。

缓冲技术原理:此对象中封装了数组,将数据存入,再一次性取出。

对应类

BufferedWriter

BufferedReader

缓冲区要结合流才可以使用。

在流的基础上对流的功能进行了增强。

装饰设计模式

简述

当想对已有对象进行功能增强时,可定义类:将已有对象传入,基于已有对象的功能,并提供加强功能,那么自定义的该类称之为装饰类。

特点

装饰类通常都会通过构造方法接收被装饰的对象,并基于被装饰的对象的功能,提供更强的功能。

装饰和继承的区别:

装饰模式比继承要灵活。避免了继承体系的臃肿,且降低了类与类之间的关系。

装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强的功能,所以装饰类和被装饰的类通常都是属于一个体系。

从继承结构转为组合结构。

注:在定义类的时候,不要以继承为主;可通过装饰设计模式进行增强类功能。灵活性较强,当装饰类中的功能不适合,可再使用被装饰类的功能。

BufferedReader的原理。

使用流的read方法从源中读取一批数据存储到缓冲区的数组中。

通过计数器记录住存储的元素个数。

通过数组的角标来获取数组中的元素(从缓冲区中取数据).

指针会不断的自增,当增到数组长度,会归0.计数器会自减,当减到0时,就在从源拿一批数据进缓冲区。

自定义BufferedReader:

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

/**
* 自定义的读取缓冲区。其实就是模拟一个BufferedReader.
*
* 分析: 缓冲区中无非就是封装了一个数组, 并对外提供了更多的方法对数组进行访问。 其实这些方法最终操作的都是数组的角标。
*
* 缓冲的原理: 其实就是从源中获取一批数据装进缓冲区中。 在从缓冲区中不断的取出一个一个数据。
*
* 在此次取完后,在从源中继续取一批数据进缓冲区。 当源中的数据取光时,用-1作为结束标记。
*
*
* @author Administrator
*
*/
public class MyBufferedReader extends Reader {

private Reader r;

// 定义一个数组作为缓冲区。
private char[] buf = new char[1024];

// 定义一个指针用于操作这个数组中的元素。当操作到最后一个元素后,指针应该归零。
private int pos = 0;

// 定义一个计数器用于记录缓冲区中的数据个数。 当该数据减到0,就从源中继续获取数据到缓冲区中。
private int count = 0;

MyBufferedReader(Reader r) {
this.r = r;
}

/**
* 该方法从缓冲区中一次取一个字符。
*
* @return
* @throws IOException
*/
public int myRead() throws IOException {

// 从源中获取一批数据到缓冲区中。需要先做判断,只有计数器为0时,才需要从源中获取数据。
if (count == 0) {
count = r.read(buf);
pos = 0; // 每次获取数据到缓冲区后,角标归零.
}
if (count < 0)
return -1; // 代表流读完了

char ch = buf[pos++];
count--;
return ch;
}

public String myReadLine() throws IOException {

StringBuilder sb = new StringBuilder();

int ch = 0;
while ((ch = myRead()) != -1) {

if (ch == '\r')
continue;
if (ch == '\n')
return sb.toString();
// 将从缓冲区中读到的字符,存储到缓存行数据的缓冲区中。
sb.append((char) ch);

}

if (sb.length() != 0)
return sb.toString();
return null;
}

public void myClose() throws IOException {

r.close();
}

@Override
public int read(char[] cbuf, int off, int len) throws IOException {

return 0;
}

@Override
public void close() throws IOException {
}
}


字节流

基本操作与字符流类相同

但它不仅可以操作字符,还可以操作其他媒体文件

字节流继承体系简图



字符流的缓冲区

同样是提高了字节流的读写效率。

读写特点:

read():会将字节byte型值提升为int型值

write():会将int型强转为byte型,即保留二进制数的最后八位。

转换流

InputStreamReader, OutputStreamWriter

转换流的由来

字符流与字节流之间的桥梁

方便了字符流与字节流之间的操作

转换流的应用

字节流中的数据都是字符时,转成字符流操作更高效。

标准输入输出流

System类中的字段:in,out。

它们各代表了系统标准的输入和输出设备。

默认输入设备是键盘,输出设备是显示器。

System.in的类型是InputStream.

System.out的类型是PrintStream是OutputStream的子类FilterOutputStream的子类.

示例

InputStreamReader将字节流通向字符流

获取键盘录入对象。

InputStream in=System.in;


将字节流对象转成字符流对象,使用转换流。

InputStreamReaderisr=new InputStreamReader(in);


为了提高效率,将字符串进行缓冲区技术高效操作。使用BufferedReader

BufferedReaderbr=new BufferedReader(isr);


//键盘录入最常见写法

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


OutputStreamWriter字符流通向字节流

字符通向字节:录入的是字符,存到硬盘上的是字节。步骤和InputStreamReader转换流一样。

/*
需求:将键盘录入的数据,显示在控制台,当输入over时,表示结束
源:键盘录入。
目的:控制台。

*/
import java.io.*;

class TransStreamDemo {
public static void main(String[] args) throws IOException {
// 获取键盘录入对象。
// InputStream in=System.in;
// 将字节流对象转成字符流对象,使用转换流。
// InputStreamReader isr=new InputStreamReader(in);
// 为了提高效率,将字符串进行缓冲区技术高效操作。使用BufferedReader
// BufferedReader br=new BufferedReader(isr);

// 键盘录入最常见写法
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

// 字符流通向字节流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
System.out));

String s = null;
while ((s = in.readLine()) != null) {
if ("over".equals(s))
break;
bw.write(s.toUpperCase());// 写入数据
bw.newLine();// 换行
bw.flush();// 刷新

}
bw.close();// 关闭流资源
in.close();
}
}


IO流的操作规律总结

明确体系:

数据源:InputStream ,Reader

数据汇:OutputStream,Writer

明确数据:因为数据分两种:字节,字符。

数据源:是否是纯文本数据呢?

是:Reader

否:InputStream

数据汇:

是:Writer

否:OutputStream

明确设备:

数据源:

键盘:System.in

硬盘:FileXXX

内存:数组。

网络:socket socket.getInputStream();

数据汇:

控制台:System.out

硬盘:FileXXX

内存:数组

网络:socket socket.getOutputStream();

明确额外功能:

需要转换?是,使用转换流。InputStreamReader OutputStreamWriter

需要高效?是,使用缓冲区。Buffered

需要其他?

示例:

复制一个文本文件。

明确体系:

源:InputStream ,Reader

目的:OutputStream ,Writer

明确数据:

源:是纯文本吗?是 Reader

目的;是纯文本吗?是 Writer

明确设备:

源:硬盘上的一个文件。 FileReader

目的:硬盘上的一个文件。FileWriter

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

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

需要额外功能吗?

需要,高效,使用buffer

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

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

读取键盘录入,将数据存储到一个文件中。

明确体系:

源:InputStream ,Reader

目的:OutputStream ,Writer

明确数据:

源:是纯文本吗?是 Reader

目的;是纯文本吗?是 Writer

明确设备:

源:键盘,System.in

目的:硬盘,FileWriter

InputStream in = System.in;

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

需要额外功能吗?

需要,因为源明确的体系时Reader。可是源的设备是System.in。

所以为了方便于操作文本数据,将源转成字符流。需要转换流。InputStreamReader

InputStreamReader isr = new InputStreamReader(System.in);

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

需要高效不?需要。Buffer

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

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

读取一个文本文件,将数据展现在控制台上。

明确体系:

源:InputStream ,Reader

目的:OutputStream ,Writer

明确数据:

源:是纯文本吗?是 Reader

目的;是纯文本吗?是 Writer

明确设备:

源:硬盘文件,FileReader。

目的:控制台:System.out。

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

OutputStream out = System.out;

需要额外功能?

因为源是文本数据,确定是Writer体系。所以为了方便操作字符数据,

需要使用字符流,但是目的又是一个字节输出流。

需要一个转换流,OutputStreamWriter

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

OutputStreamWriter osw = new OutputStreamWriter(System.out);

需要高效吗?需要。

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

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

读取键盘录入,将数据展现在控制台上。

明确体系:

源:InputStream ,Reader

目的:OutputStream ,Writer

明确数据:

源:是纯文本吗?是 Reader

目的;是纯文本吗?是 Writer

明确设备:

源:键盘:System.in

目的:控制台:System.out

InputStream in = System.in;

OutputStream out = System.out;

需要额外功能吗?

因为处理的数据是文本数据,同时确定是字符流体系。

为方便操作字符数据的可以将源和目的都转成字符流。使用转换流。

为了提高效率,使用Buffer

BufferedReader bufr =new BufferedReader(new InputStreamReader(Systme.in));

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

读取一个文本文件,将文件按照指定的编码表UTF-8进行存储,保存到另一个文件中。

明确体系:

源:InputStream ,Reader

目的:OutputStream ,Writer

明确数据:

源:是纯文本吗?是 Reader

目的;是纯文本吗?是 Writer

明确设备:

源:硬盘:FileReader.

目的:硬盘:FileWriter

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

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

额外功能:

注意:目的中虽然是一个文件,但是需要指定编码表。

而直接操作文本文件的FileWriter本身内置的是本地默认码表。无法明确具体指定码表。

这时就需要转换功能。OutputStreamWriter,而这个转换流需要接受一个字节输出流,而且

对应的目的是一个文件。这时就使用字节输出流中的操作文件的流对象。FileOutputStream.

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

OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(“b.txt”),”UTF-8”);

需要高效吗?

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

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

IO包中的其他类

RandomAccessFile

随机访问文件,自身具备读写的方法。

通过skipBytes(int x),seek(int x)来达到随机访问。

管道流

PipedInputStream和PipedOutputStream

输入输出可以直接进行连接,通过结合线程使用。

打印流

PrintWriter与PrintStream

可以直接操作输入流和文件。

序列流

SequenceInputStream

对多个流进行合并。

操作对象

ObjectInputStream与ObjectOutputStream

被操作的对象需要实现Serializable (标记接口);

操作基本数据类型

DataInputStream与DataOutputStream

操作字节数组

ByteArrayInputStream与ByteArrayOutputStream

操作字符数组

CharArrayReader与CharArrayWrite

操作字符串

StringReader 与 StringWriter

IO流体系

字符流:
Reader
|--BufferedReader
|--LineNumberReader
|--CharArrayReader
|--StringReader
|--InputStreamReaer
|--FileReader
Writer
|--BufferedWriter
|--CharArrayWriter
|--StringWriter
|--OutputStreamWriter
|--FileWriter
|--PrintWriter

字节流:
InputStream
|--FileInputStream
|--FilterInputStream
|--BufferedInputStream
|--DataInputStream
|--ByteArrayInputStream
|--ObjectInputStream
|--SequenceInputStream
|--PipedInputStream
OutputStream
|--FileOutputStream
|--FilterOutputStream
|--BufferedOutputStream
|--DataOutputStream
|--ByteArrayOutputStream
|--ObjectOutputStream
|--PipedOutputStream
|--PrintStream
RandomAccessFile
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: