java输入与输出的IO流技术

本文详细介绍了Java中的IO流体系,包括字节流和字符流的基本概念、常用类及其使用方法,并探讨了装饰设计模式的应用。此外,还讲解了转换流的作用及如何提高流操作的效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、IO流的体系架构

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

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

1InputStream  2OutputStream.

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

1Reader 2Writer

注意:

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、字节流中常见的类

1FileInputStream

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

2FileOutputStream

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

 

3BufferedInputStream

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

 

4BufferedOutputStream

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

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

 

             

       }

}

五、转换流:

1InputStreamReader

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

2OutputStreamWriter

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

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,转换。

      

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值