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

黑马程序员_java输入与输出的IO流技术

2013-02-11 16:52 134 查看
------- android培训java培训、期待与您交流! ----------
一、IO流的体系架构

IO流从顶层上分总共分出两个体系,一个是字节流,一个是字符流。

1、字节流的两个顶层父类:

1,InputStream 2,OutputStream.

2、字符流的两个顶层父类:

1,Reader 2,Writer

注意:

1)这些体系的子类都以父类名作为后缀。

而且子类名的前缀就是该对象的功能。

2)输入流和输出流相对于内存设备而言.

将外设中的数据读取到内存中:输入

将内存的数写入到外设中:输出。

二、字符流

1、字符流的由来

无论什么流,其底层的最终实现结构其实都是字节流,但当字节流读取文字字节数据后,不直接操作而是先查指定的编码表,获取对应的文字,然后再对这个文字进行操作,这就变成了字符流,简单的说:字符流=字节流+编码表

2、字符流中的常见类

1)FileReader

此类用于从硬盘上的数据文件读取数据。

2)FileWriter

此类用于把数据写到硬盘上的数据文件上。

3)BufferedReader

可以从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

4)BufferedWriter

可以将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。

3、字符流的演示代码如下:

import java.io.*;

class BufferedReaderDemo

{

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

{

//创建一个读取流对象和文件相关联。

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

//为了提高效率。加入缓冲技术。将字符读取流对象作为参数传递给缓冲对象的构造函数。

BufferedReader bufr = new BufferedReader(fr);

String line = null;

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

{

System.out.print(line);

}

bufr.close();

}

}

三、装饰设计模式

1、什么时候使用装饰设计模式

对一组对象的功能进行增强时,就可以使用该模式进行问题的解决。

2、装饰和继承的区别

由于装饰和继承都能实现一个同样的特点:进行功能的扩展增强。那么它们两者之间有什么区别呢?

1)模式的出现及演化

首先有一个继承体系。

Writer

|--TextWriter:用于操作文本

|--MediaWriter:用于操作媒体。

想要对操作的动作进行效率的提高。

按照面向对象,可以通过继承对具体的进行功能的扩展。

效率提高需要加入缓冲技术。

Writer

|--TextWriter:用于操作文本

|--BufferTextWriter:加入了缓冲技术的操作文本的对象。

|--MediaWriter:用于操作媒体。

|--BufferMediaWriter:

到这里就解决问题了。但是这样做好像并不理想。

如果这个体系进行功能扩展,就要又增加很多流对象。

那么这个流要提高效率,是不是也要产生子类呢?是。这时就会发现只为提高功能,进行的继承,将直接导致继承体系越来越臃肿。不够灵活。

现在开始重新思考这个问题:

既然加入的都是同一种技术--缓冲。

前一种是让缓冲和具体的对象相结合。

可不可以将缓冲进行单独的封装,哪个对象需要缓冲就将哪个对象和缓冲关联。

class Buffer{

Buffer(TextWriter w)

{}

Buffer(MediaWirter w)

{

}

}

class BufferWriter extends Writer{

BufferWriter(Writer w)

{

}

}

Writer

|--TextWriter:用于操作文本

|--MediaWriter:用于操作媒体。

|--BufferWriter:用于提高效率。

由此就实现了程序的功能,且装饰比继承更灵活。

特点:装饰类和被装饰类都必须所属同一个接口或者父类。

四、字节流

1、字节流中常见的类

1)FileInputStream

此类从文件系统中的某个文件中获得输入字节。哪些文件可用取决于主机环境。适合用于读取诸如图像数据之类的原始字节流。

2)FileOutputStream

文件输出流是用于将数据写入 File
或 FileDescriptor 的输出流。文件是否可用或能否可以被创建取决于基础平台。特别是某些平台一次只允许一个 FileOutputStream(或其他文件写入对象)打开文件进行写入。在这种情况下,如果所涉及的文件已经打开,则此类中的构造方法将失败。

3)BufferedInputStream

此类为另一个输入流添加一些功能,即缓冲输入以及支持 mark
和 reset 方法的能力。在创建 BufferedInputStream
时,会创建一个内部缓冲区数组。在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。mark
操作记录输入流中的某个点,reset 操作使得在从包含的输入流中获取新字节之前,再次读取自最后一次 mark
操作后读取的所有字节。

4)BufferedOutputStream

该类实现缓冲的输出流。通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统。

2、字节流的演示代码如下:

import java.io.*;

class FileStream

{

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

{

readFile_3();

}

public static void readFile_3()throws IOException

{

FileInputStream fis = new FileInputStream("fos.txt");

// int num = fis.available();

byte[] buf = new byte[fis.available()];//定义一个刚刚好的缓冲区。不用在循环了。

fis.read(buf);

System.out.println(new String(buf));

fis.close();

}

public static void readFile_2()throws IOException

{

FileInputStream fis = new FileInputStream("fos.txt");

byte[] buf = new byte[1024];

int len = 0;

while((len=fis.read(buf))!=-1)

{

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

}

fis.close();

}

public static void readFile_1()throws IOException

{

FileInputStream fis = new FileInputStream("fos.txt");

int ch = 0;

while((ch=fis.read())!=-1)

{

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

}

fis.close();

}

public static void writeFile()throws IOException

{

FileOutputStream fos = new FileOutputStream("fos.txt");

fos.write("abcde".getBytes());

fos.close();

}

}

五、转换流:

1、InputStreamReader


字节到字符的桥梁。解码。

2、OutputStreamWriter:

字符到字节的桥梁。编码。

3、转换流示例代码如下:

import java.io.*;

class TransStreamDemo

{

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

{

//获取键盘录入对象。

//InputStream in = System.in;

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

//InputStreamReader isr = new InputStreamReader(in);

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

//BufferedReader bufr = new BufferedReader(isr);

//键盘的最常见写法。

BufferedReader bufr =

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

// OutputStream out = System.out;

// OutputStreamWriter osw = new OutputStreamWriter(out);

// BufferedWriter bufw = new BufferedWriter(osw);

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

String line = null;

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

{

if("over".equals(line))

break;

bufw.write(line.toUpperCase());

bufw.newLine();

bufw.flush();

}

bufr.close();

}

}

六、流的操作规律:

之所以要弄清楚这个规律,是因为流对象太多,开发时不知道用哪个对象合适。

想要知道开发时用到哪些对象。只要通过四个明确即可。

1,明确源和目的(汇)

源:InputStream Reader

目的:OutputStream Writer

2,明确数据是否是纯文本数据。

源:是纯文本:Reader

否:InputStream

目的:是纯文本 Writer

否:OutputStream

到这里,就可以明确需求中具体要使用哪个体系。

3,明确具体的设备。

源设备:

硬盘:File

键盘:System.in

内存:数组

网络:Socket流

目的设备:

硬盘:File

控制台:System.out

内存:数组

网络:Socket流

4,是否需要其他额外功能。

1,是否需要高效(缓冲区);

是,就加上buffer.

2,转换。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: