java IO流(一) --字节流

来源:互联网 发布:淘宝店如何装修 编辑:程序博客网 时间:2024/05/22 10:27

简介

Java语言的输入输出功能借助于输入输出包java.io,通过流(Stream)来实现,用统一的接口来表示,从而是程序设计简单明了。

流(Stream)是计算机各部件之间数据流动。按数据传输方向分为输入流(程序从外设读入数据流)和输出流(程序往外设写入数据流)。按内容划分为字节流和字符流

采用数据流来处理输入输出的目的是使程序的输入输出操作独立于相关设备。也就是说,对任何设备的输入输出,只要针对流做处理就可以了,从而增强了设备的可移植性。

InputStream、OutStream、Reader和Writer是抽象类,用于数据流的输入输出;File是文件类,用于对磁盘文件于文件夹的管理;RandomAccessFile是随机访问文件类,用于实现对磁盘文件的随机读写操作:
这里写图片描述

下面我们先来介绍字节流

InputStream和OutStream用来处理以位(bit)为单位的流的抽象类,除了可以用来处理二进制文件,也可以处理文本文件。

注意:不提倡字节流处理文本文件,因为如果文件中有汉字,可能会出现乱码,建议用字符流处理文本文件

1、 InputStream类

InputStream抽象类中包含一套所有字节输入的方法,可以完成基本的从输入流读入数据的功能。

常用方法:

int available() //返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)的估计字节数。 void close() //关闭此输入流并释放与该流关联的所有系统资源。 void mark(int readlimit) //在此输入流中标记当前的位置。 boolean markSupported() //测试此输入流是否支持 mark 和 reset 方法。abstract  int read() //从输入流中读取数据的下一个字节。 int read(byte[] b) //从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。int read(byte[] b, int off, int len) //将输入流中最多 len 个数据字节读入 byte 数组。 void reset() //将此流重新定位到最后一次对此输入流调用 mark 方法时的位置。 long skip(long n) //跳过和丢弃此输入流中数据的 n 个字节。 

2、 OutputStream类

OutputStream抽象类中包含一套所有字节输出的方法,可以完成基本的输出流写入数据的功能。

void close() //关闭此输出流并释放与此流有关的所有系统资源。 void flush() //刷新此输出流并强制写出所有缓冲的输出字节。 void write(byte[] b) //将 b.length 个字节从指定的 byte 数组写入此输出流。void write(byte[] b, int off, int len) //将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。abstract  void write(int b) //将指定的字节写入此输出流。 

提示:以上已介绍了这两个抽象类的基本方法,其子类不再重复介绍这些方法

3、文件字节流 FileInputStream和FileOutputStream类

这两个实现类主要负责完成对本地磁盘文件的顺序输入输出操作。在生成FileInputStream类的对象时,若指定文件找不到,这抛出FileNotFoundException异常,该异常必须捕捉或声明抛出;在输出FileOutputStream的对象时,若找不到指定的文件,则创建一个新文件,若已存在,则清空原文件的内容。在进行文件的读写操作时会产生IOException异常,该异常必须捕捉或声明抛出。

FileInputStream的构造方法:

public FilterInputStream(String name) //以名为name的文件为数据源建立输入流public FilterInputStream(File file) //以指定名称的文件对象file为数据源建立文件输入流public FilterInputStream(FileDescriptor fdObj) //根据文件描述符对象fdObj为输入端建立一个文件输入流 

FileOutputStream的构造方法:

public FilterOutputStream(String name) //以指定名称的文件为接收端建立文件输出流public FilterOutputStream(String name,boolean append) //以指定名称的文件为接收端建立文件输出流,并指定写入方式,append为true时输出字节被写到文件的末尾public FilterOutputStream(File file) //以指定名称的文件对象为接收端建立文件输出流public FilterOutputStream(FileDescriptor fdObj) //根据文件描述符对象fdObj建立一个文件输出流

FileDescriptor是文件描述符类,不能实例化,文件描述符的主要实际用途是创建一个包含该结构的 FileInputStream 或 FileOutputStream。 该类有三个静态成员:

in — 标准输入(键盘)的描述符
out — 标准输出(屏幕)的描述符
err — 标准错误输出(屏幕)的描述符

例1:

public static void main(String[] args) {        FileInputStream fin;        FileOutputStream fout;        char ch;        int data;        try{            fin =new FileInputStream(FileDescriptor.in);//new一个输入流对象            fout = new FileOutputStream(FileDescriptor.out);//new一个输出流            System.out.println("请输入一串字符,并以#结束:");            while((ch=(char)fin.read())!='#'){//读取                fout.write(ch);//写入            }            fin.close();//关闭输入输出流,释放资源            fout.close();        }catch (Exception e) {            System.out.println("File not found");        }}

例2

public static void main(String[] args) throws IOException{        FileInputStream fin=new FileInputStream("f:\\2.png");        FileOutputStream fout=new FileOutputStream("f:\\2_1.jpg");        System.out.println("文件大小:"+fin.available()+"字节");        byte[] b=new byte[fin.available()];        fin.read(b);        fout.write(b);        System.out.println("文件已被复制改名");        fin.close();        fout.close();       }

4、顺序输入流类SequenceInputStream

改实现类的功能是将多个输入流顺序的连接在一起,形成单一的数据流,没有对应的输出数据流存在。

构造方法:

SequenceInputStream(Enumeration<? extends InputStream> e) //创建一个串行输入流,链接枚举对象e中所有的输入流SequenceInputStream(InputStream s1, InputStream s2) //创建一个串行输入流,链接输入流s1和s2

5、管道输入输出流 PipedInputStream和 PipedOutputStream

这两个实现类提供了利用管道方式进行数据输入输出管理。管道流用来将一个程序或线程的输出连接到另一个程序或线程作为输入,使得相连线程能够交换数据,从而实现程序内部线程间的通信或不同程序间通信。这两个类必须结合使用。

PipedInputStream构造方法:

PipedInputStream(int pipeSize) //创建一个尚未连接的 PipedInputStream,并对管道缓冲区使用指定的管道大小。  PipedInputStream(PipedOutputStream src) //创建 PipedInputStream,使其连接到管道输出流 src。  PipedInputStream(PipedOutputStream src, int pipeSize)  //创建一个 PipedInputStream,使其连接到管道输出流 src,并对管道缓冲区使用指定的管道大小。 

PipedInputStream方法:

void connect(PipedOutputStream src) //使此管道输入流连接到管道输出流 src。void receive(int b)  接收数据字节。 

PipedOutputStream构造方法:

PipedOutputStream(PipedInputStream snk) //创建连接到指定管道输入流的管道输出流。

PipedOutputStream方法:

void connect(PipedInputStream snk) //将此管道输出流连接到接收者。 

6、过滤输入输出流 FilterInputStream和 FilterOutputStream

这两个类分别实现了在数据的读、写操作的同时进行数据处理。这两个类也是抽象类,它们又分别派生数据输入流类DataInputStream和数据输出流类DateOutputStream等子类。过滤输入输出流的主要特点就是建立在基本输入输出流之上,并在输入输出数据的同时能对所传输的数据做指定类型或格式的转换,即可以对二进制字节数据的理解和编码转换。

有时按字节为基本单位进行数据读写处理并不方便,而是希望按数据类型为基本单位进行读取。在java中,按照基本数据类型进行读写的就是DataInputStream和DataOutputStream,这两个类的对象是过滤流。将基本字节流自动转成按基本数据类型进行读写的过滤流。然后利用流串接的方式,以达到数据转换的目的。

这两个数据过滤流类分别实现了DataInput和DataOutput两个接口中定义的独立于具体机器的带格式的读写操作,从而实现了对不同类型数据的读写。

DataInputStream构造方法:

DataInputStream(InputStream in) //建立一个新的数据输入流,从指定的输入流in读数据

DataInputStream方法:

boolean readBoolean() //读取一个输入字节,如果该字节不是零,则返回 true,如果是零,则返回 false。byte readByte() //读取并返回一个字节。char readChar() //读取两个字节并返回一个 char 值。double readDouble() //读取八个字节并返回一个 double 值。float readFloat() //读取四个字节并返回一个 float 值。int readInt() //读取四个字节并返回一个 int 值。long readLong() //读取八个字节并返回一个 long 值。short readShort() //读取两个字节并返回一个 short 值。       

DataOutputStream构造方法:

DataOutputStream(OutputStream out) //创建一个新的数据输出流,将数据写入指定基础输出流。

DataOutputStream方法:

void writeBoolean(boolean v) //将一个 boolean 值以 1-byte值形式写入基础输出流。 void writeByte(int v) //向流中写入一字节,写入v的最低一字节,其他字节舍弃。 void writeBytes(String s) //将字符串按字节顺序写出到基础输出流中。void writeChar(int v) //向流写入v的最低2字节,其他字节舍弃void writeChars(String s) //将字符串按字符顺序写入基础输出流。 void writeDouble(double v)  //向流中写入v的8字节void writeFloat(float v) //向流中写入v的4字节void writeInt(int v) //向流中写入v的4字节void writeLong(long v) //向流中写入v的8字节void writeShort(int v) //向流中写入v的最低2字节,其他字节舍弃           

7、标准输入输出流

对于一般计算机系统,标准输入输出指的是键盘和显示屏。java在System类中定义了静态流System.in、System.out、System.err。这三个流对象定义在java.lang.System包中,不用import导入,java源程序编译时自动装载。

标准输入System.in是FilterInputStream的子类BufferedInputStream的对象,调用System.in.read()从键盘读入一字节数据,要捕捉异常。

标准输出System.out是FilterOutputStream的子类打印输出流PrintStream的对象,调用print()和println()方法向屏幕输出。

标准错误System.err也是PrintStream派生的错误流,调用print()和println()
err也使用与out同样的方法,但err会立即显示指定的错误信息让用户指定。