吾知网

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 6290|回复: 0
打印 上一主题 下一主题

android 输入输出流小结(1)

[复制链接]
跳转到指定楼层
楼主
发表于 2015-11-21 16:45:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

stream:任何有能力产出数据的数据源,或是任何有能力接收数据的接收源。我们经常使用的stream基本上都是从这两个类继承而来:Inputstream和Outputstream

I/O流的类型:字节流和字符流

字节流:以字节为单位向stream中写入或者从stream中读取。一般的二进制数据都使用字节流,比如声音和图像等

字符流:以Unicode字符为单位向stream中写入或者从stream中读取。要处理16位的Unicode字符流就需要引进writer和reader,加入了writer和reader的新的i/o类库既可以处理8位的字节流,也可以处理16位的Unicode字符流。这个主要是为了解决国际化的问题。

输入输出流的层次结构图


下面介绍几种比较常见的输入输出流

1.inputStream:产生数据的数据源,inputStream类是抽象类,不能够创建对象,需要通过子类来实现。比较常见的方法如下:

(1)       public abstract int read( ):读取一个byte的数据,返回值是高位补0的int类型值。

(2)       public int read(byte b[ ]):读取b.length个字节的数据放到b数组中。返回值是读取的字节数。该方法实际上是调用下一个方法实现的
(3)       public int read(byte b[ ], int off, int len):从输入流中最多读取len个字节的数据,存放到偏移量为off的b数组中。
(4)       public int available( ):返回输入流中可以读取的字节数。注意:若输入阻塞,当前线程将被挂起,如果InputStream对象调用这个方法的话,它只会返回0,这个方法必须由继承InputStream类的子类对象调用才有用,
(5)       public long skip(long n):忽略输入流中的n个字节,返回值是实际忽略的字节数, 跳过一些字节来读取
(6)       public int close( ) :我们在使用完后,必须对我们打开的流进行关闭.
2.outputStream:可以接收数据的接收源,和inputStream一样,也是抽象类。比较常用的方法:
(1). public void write(byte b[ ]):将参数b中的字节写到输出流。

(2). public void write(byte b[ ], int off, int len) :将参数b的从偏移量off开始的len个字节写到输出流。

(3). public abstract void write(int b) :先将int转换为byte类型,把低字节写入到输出流中。

(4). public void flush( ) : 将数据缓冲区中数据全部输出,并清空缓冲区。

(5). public void close( ) : 关闭输出流并释放与流相关的系统资源。
3.FileInputStream: inputStream类的子类,处理以文件作为输入源的数据源。常用方法:
方式1:

File fin=new File("d:/abc.txt");

   FileInputStream in=new FileInputStream(fin);

方式2:

   FileInputStream in=new

            FileInputStream("d: /abc.txt");

方式3:

构造函数将 FileDescriptor()对象作为其参数。

FileDescriptor() fd=new FileDescriptor();

FileInputStream f2=new FileInputStream(fd);
4.FileOutputStream:用来处理文件作为输出地的stream。常用的方法:
方式1:

File f=new File("d:/abc.txt");

FileOutputStream out=new FileOutputStream (f);

方式2:

   FileOutputStream out=new

       FileOutputStream("d:/abc.txt");

方式3:构造函数将 FileDescriptor()对象作为其参数。

FileDescriptor() fd=new FileDescriptor();

FileOutputStream f2=new FileOutputStream(fd);

方式4:构造函数将文件名作为其第一参数,将布尔值作为第二参数。

FileOutputStream f=new FileOutputStream("d:/abc.txt",true);

注意:

(1)文件中写数据时,若文件已经存在,则覆盖存在的文件;(2)的读/写操作结束时,应调用close方法关闭流。
5.BufferedInputStream,BufferedOutputStream允许程序在不降低系统性能的情况下一次一个字节的从流中读取或者写入数据
BufferInputstream定义了两种构造函数
(1)      BufferInputStreamb= new BufferInputstream(in);
(2)      BufferInputStreamb=new BufferInputStream(in,size)
第二个参数表示指定缓冲器的大小。
同样BufferOutputStream也有两种构造函数。一次一个字节的向流中写数据。
Unicode字符流的读取和写入:
java.io.Reader和java.io.InputStream组成了Java输入类。Reader用于读入16位字符,也就是Unicode编码的字符;而InputStream用于读入ASCII字符和二进制数据。
Reader和Writer的体系结构
(1)FileReader
  FileReader:主要用来读取字符文件,使用缺省的字符编码,有三种构造函数:
--将文件名作为字符串
  FileReaderf=new FileReader(“c:/temp.txt”);
--构造函数将File对象作为其参数。
Filef=new file(“c:/temp.txt”);
FileReaderf1=new FileReader(f);
--构造函数将FileDescriptor对象作为参数
FileDescriptor()fd=new FileDescriptor()
FileReaderf2=new FileReader(fd);
FileWriter:将字符类型数据写入文件
PublicFileWriter(file f);
(2)   charArrayReader
将字符数组作为输入流,构造函数为:
publicCharArrayReader(char[] ch);
chararrayWrite:将字符缓冲器用作输出。
PublicCharArrayWriter();
(3)   StringReader
读取字符串,构造函数如下:
publicStringReader(String s);
(4)   InputStreamReader
从输入流读取字节,在将它们转换成字符。
PublicinputstreamReader(inputstream is);
(5)   FilterReader
允许过滤字符流
protectedfilterReader(Reader r);
(6)   BufferReader
接受Reader对象作为参数,并对其添加字符缓冲器,使用readline()方法可以读取一行。
PublicBufferReader(Reader r);

下面举一个输入输出流的简单的例子:使用到FileInputStreamOutPutStream,就是文件的复制
代码如下,比较简单,第一种仅使用了FileInputStream,第二种还使用了BufferedInputStream,两个demo的结果是一样的。
[html] view plaincopy


  • <span style="font-size:14px;">import java.io.*;  
  •   
  • public class FileStreamDemo {  
  •   
  •     public static void main(String[] args) {  
  •   
  •         try {  
  •   
  •            // 来源文件  
  •   
  •             FileInputStream in = new FileInputStream("D:/b.txt");  
  •   
  •             // 目的文件  
  •   
  •             FileOutputStream out = new FileOutputStream("C:/a.txt");  
  •   
  •             byte[] bytearray = new byte[1024];  
  •   
  •             do {  
  •   
  •                 in.read(bytearray, 0, 1024);  
  •   
  •                out.write(bytearray);  
  •   
  •             } while (in.available() > 0);  
  •   
  •             in.close();  
  •   
  •             out.close();  
  •   
  •         } catch (ArrayIndexOutOfBoundsException e) {  
  •   
  •             e.printStackTrace();  
  •   
  •         } catch (IOException e) {  
  •   
  •             e.printStackTrace();  
  •   
  •         }  
  •   
  •     }  
  •   
  • }</span>  


[html] view plaincopy


  • <span style="font-size:14px;">mport java.io.*;  
  •   
  •   
  •   
  • public class FileStreamDemo {  
  •   
  •     public static void main(String[] args) {  
  •   
  •         try {  
  •   
  •             // 来源文件  
  •   
  •             FileInputStream in = new FileInputStream("D:/b.txt");  
  •   
  •             // 目的文件  
  •   
  •             FileOutputStream out = new FileOutputStream("C:/a.txt");  
  •   
  •             BufferedInputStream bufferedIn = new BufferedInputStream(in);  
  •   
  •             BufferedOutputStream bufferedOut = new BufferedOutputStream(out);  
  •   
  •             byte[] data = new byte[1];  
  •   
  •             while (bufferedIn.read(data) != -1) {  
  •   
  •                 bufferedOut.write(data);  
  •   
  •             }  
  •   
  •             //将缓冲区中的数据全部写出  
  •   
  •             bufferedOut.flush();  
  •   
  •             //关闭流  
  •   
  •             bufferedIn.close();  
  •   
  •             bufferedOut.close();  
  •   
  •         } catch (ArrayIndexOutOfBoundsException e) {  
  •   
  •             e.printStackTrace();  
  •   
  •         } catch (IOException e) {  
  •   
  •             e.printStackTrace();  
  •   
  •         }  
  •   
  •     }  
  •   
  • }</span>  


下面插一段题外话:
在使用HttpUrlConnection向服务器端发送请求的时候,http头配置好了的时候,需要通过outputStream流写入http请求的正文,实际上outputStream不是一个网络流,充其量是个字符串流,往里面写入的东西不会立即发送到网络,而是存在于内存缓冲区中,待outputStream流关闭时,根据输入的内容生成http正文。至此,http请求的东西已经全部准备就绪。在getInputStream()函数调用的时候,就会把准备好的http请求正式发送到服务器了,然后返回一个输入流,用于读取服务器对于此次http请求的返回信息。由于http请求getInputStream的时候已经发送出去了(包括http头和正文),因此在getInputStream()函数之后对connection对象进行设置(对http头的信息进行修改)或者写outputStream(对正文进行修改) 都是没有意义的了,执行这些操作会导致异常的发生。
在进行android网络编程连接服务器的时候,这一点弄得不是很明白,今天终于弄懂了。


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|吾知网 ( 粤ICP备13013563号-1 )

GMT+8, 2024-11-22 09:35 , Processed in 1.109382 second(s), 8 queries , Memcache On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表