理解Java的IO流

1.输入流和输出流 

a: 数据从内存到硬盘,通常称为输出流。划分输入/输出流是从程序运行所在内存来考虑的,所以是输出流,而不是输入流。

  b: 数据从服务器通过网络流向客户端,在这种情况下,server的内存负责将数据输出到网络,因此server端的程序使用输出流;client端的内存负责从网络里读取数据,因此client端的程序应该使用输入流。

 

注:

   Java的输入流主要由InputStreamReader作为基类,而输出流则主要由OutputStreamWriter作为基类。

 

2.字节流和字符流

字节流和字符流用法几乎完全一样,区别在于字节流和字符流所操作的数据单元不同:字节流操作的最小数据单元是8位的字节,而字符流操作的最小数据单元是16位字符。

字节流主要由InputStreamOutputStream作为基类;

字符流主要由ReaderWriter作为基类。

 

3.节点流和处理流

按流的角色分,可以分为节点流和处理流。

从一个特定的IO设备(如磁盘、网络)读/写数据的流,称为节点流,节点流通常被称为低级流。

处理流则用于对一个已存在的流进行连接和封装,通过封装后流来实现数据读/写功能。处理流也被称为高级流.

 

: java使用处理流来包装节点流是一种典型的装饰设计模式,通过使用处理流包装不同的节点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输/输出功能。

 

3.1 InputStream Reader

       InputStreamReader都是抽象类,本身不能创建实例,但是它们分别有一个用于读取文件的输入流:FileInputStream FileReader,他们都是节点流----会直接和指定文件关联。

//创建字节输入流

FileInputStream fis = newFileInputStream("D:\\WorkSpace\\FileInputStreamTest.java");

              //创建一个长度为1024的“竹筒”

              byte[] bbuf = new byte[1024];

              //用于保存实际读取的字节数

              int hasRead = 0;

              try {

                     //使用循环来重复“取水”过程

                     while ((hasRead = fis.read(bbuf))> 0) {

                            System.out.println(newString(bbuf, 0, hasRead));

                     }

              } finally {

                     fis.close();

              }

 

注:fis.close()关闭该文件输入流,与JDBC编程一样,程序里打开的文件IO资源不属于内存里的资源,垃圾回收无法回收该资源,所以应该显示关闭文件IO资源。与JDBC类似的是,我们一样应该把关闭文件资源放在finally块里,这样才更安全.

 

3.2 OutputStream Writer

将某个文件的数据复制到指定的文件中。

FileInputStream fis = null;

              FileOutputStream fos = null;

              try

              {

                     //创建字节输入流

                     fis= new FileInputStream("C:\\Documents and Settings\\wh1207029\\Desktop\\修改的java\\phone.txt");

                     //创建字节输出流

                     fos= new FileOutputStream("C:\\Documents andSettings\\wh1207029\\Desktop\\newFile.txt");

                     byte[] bbuf = new byte[32];

                     int hasRead = 0;

                     //循环从输入流中取出数据

                     while((hasRead =fis.read(bbuf))>0)

                     {

                            fos.write(bbuf, 0,hasRead);

                     }

              }

              catch(IOException e)

              {

                     e.printStackTrace();

              }

              finally

              {

                     if(fis !=null){fis.close();}

                     if(fos !=null){fos.close();}

                    

              }

 

4.处理流的用法

       由于PrintStream类的输出功能非常强大,通常如果我们输出文本内容,都应该将输出流包装成PrintStream后进行输出。

       PrintStream ps = null;

              try {

                     //创建一个节点输出流:FileOutputStream

                     FileOutputStream fos = newFileOutputStream("test.txt");

                     //PrintStream来包装FileOutputStream输出流

                     ps = new PrintStream(fos);

                     //使用PrintStream 执行输出

                     ps.println("普通字符串");

                     //直接使用PrintStream输出对象

                     ps.println(new PrintStreamTest());

              } catch (IOException e) {

                     e.printStackTrace();

              }finally{

                     if(ps!=null){ps.close();}

              }

 

注:当我们使用处理流来包装底层节点流之后,关闭输入/输出流资源时,只要关闭最上层的处理流即可。关闭最上层的才处理流时,系统会自动关闭被该处理流包装的节点流。

 

5.RandomAccessFile

    RandomAccessFileJava输入/输出流体系中功能最丰富的文件内容访问类,它提供了众多的方法来访问文件内容。支持“任意访问”方式,程序可以直接跳转到文件的任意地方来读写数据。

RandomAccessFile包含了如下两个方法来操作文件记录指针:

Long getFIlePointer():返回文件记录指针的当前位置.

Void seek(long pos):将文件记录指针定位到pos位置。

 

注:RandomAccessFile既可以读文件,也可以写,包含了完全类似于InputStream的三个read()方法,也包含了OutputStream的三个write方法。除此之外,RandomAccessFile类的构造函数还需要指定一个mode参数,该参数指定RandomAccessFile的访问模式。

    RandomAccessFile依然不能向文件的指定位置插入内容,如果直接将文件记录指针移动到中间某位置后开始输出,则新输出的内容覆盖文件中原有的内容。如果需要向指定位置插入内容,程序需要先把插入点后面内容读入缓冲区,等把需要插入的数据写入文件后,再将缓冲区的内容追加到文件后面。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值