当前位置: 首页 > 工具软件 > datastream.io > 使用案例 >

java io byte_java.io 字节流

窦涵忍
2023-12-01

java.io 字节流

基类 InputStream 和 OutputStream

字节流主要操作 byte 类型数据,以 byte 数组为准,java 中每一种字节流的基本功能依赖于基本类 InputStream 和 Outputstream,他们是抽象类,不能直接使用。字节流能处理所有类型的数据(如图片、avi 等)。

InputStream

InputStream 是所有表示字节输入流的基类,继承它的子类要重新定义其中所有定义的抽象方法.InputStream是从装置来源地读取数据的抽象表示,例如System中的标准输入流in对象就是一个InputStream类型的实例。

我们先来看看InputStream类的方法:

方法

说明

read()throws IOException

从输入流中读取数据的下一个字节(抽象方法)

skip(long n) throws IOException

跳过和丢弃此输入流中数据的n个字节

available() throws IOException

返回流中可用字节数

mark(int readlimit) throws IOException

在此输入流中标记当前的位置

reset() throws IOException

将此流重新定位到最后一次对此输入流调用mark方法时的位置

markSupport() throws IOException

测试此输入流是否支持mark 和 reset 方法

close() throws IOException

关闭流

在InputStream类中,方法read()提供了三种从流中读数据的方法;

int read(): 从输入流中读一个字节,形成一个0~255之间的整数返回(是一个抽象方法)

int read(byte b[]): 从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中。

int read(byte b[], int off,int len): 从输入流中读取长度为len的数据,写入数组b中从索引off开始的位置,并返回读取的字节数。

对于这三个方法,若返回-1,表明流结束,否则,返回实际读取的字符数。

OutputStream

OutputStream 是所有表示字节输出流类的基类。子类要重新定义其中所定义的抽象方法,OutputStream 是用于将数据写入目的地的抽象表示。例如 System 中的标准输出流对象 out 其类型是 java.io.PrintStream,这个类是 OutputStream 的子类。

OutputStream 类方法:

方法

说明

write(int b)throws IOException

将指定的字节写入此输出流(抽象方法)

write(byte b[])throws IOException

将字节数组中的数据输出到流中

write(byte b[], int off, int len)throws IOException

将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流

flush()throws IOException

刷新此输出流并强制写出所有缓冲的输出字节

close()throws IOException

关闭流

看个例子

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

public class test {

/**

* 把输入流中的所有内容赋值到输出流中

* @param in

* @param out

* @throws IOException

*/

public void copy(InputStream in, OutputStream out) throws IOException {

byte[] buf = new byte[4096];

int len = in.read(buf);

//read 是一个字节一个字节地读,字节流的结尾标志是-1

while (len != -1){

out.write(buf, 0, len);

len = in.read(buf);

}

}

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

// TODO Auto-generated method stub

test t = new test();

System.out.println("输入字符:");

t.copy(System.in, System.out);

}

}

文件流

在 I/O 处理中,最常见的就是对文件的操作。java.io 包中所提供的文件操作类包括

用于读写本地文件系统中的文件:FileInputStream 和 FileOutputStream

描述本地文件系统中的文件或目录: File、FileDescriptor 和 FilenameFilter

提供对本地文件系统中文件的随机访问支持:RandomAccessFile

今天我们来学习文件流的FileInputStream 和 FileOutputStream

FileInputStream 类用于打开一个输入文件,若要打开的文件不存在,则会创建一个新的文件,否则原文件的内容会被新写入的内容所覆盖;

在进行文件的读/写操作时,会产生非运行时异常IOException,必须捕获或声明抛弃(其他的输入/输出流处理时也同样需要进行输入/输出异常处理)

文件构造方法:

//打开一个以 f 描述的文件作为输入

FileInputStream(File f)

//打开一个文件路径名为 name 的文件作为输入

FileInputStream(String name)

//创建一个以 f 描述的文件作为输出

//如果文件存在,则其内容被清空

FileOutputStream(File f)

//创建一个文件路径名为 name 的文件作为输出

//文件如果已经存在,则其内容被清空

FileOutputStream(String name)

//创建一个文件路径名为 name 的文件作为输出

//文件如果已经存在,则在该输出上输出的内容被接到原有内容之后

FileOutputStream(String name, boolean append)

示例代码 :

File f1 = new File("file1.txt");

File f2 = new File("file2.txt");

FileInputStream in = new FileInputStream(f1);

FileOutputStream out = new FileOutputStream(f2);

输入流的参数是用于指定输入的文件名,输出流的参数则是用于指定输出的文件名

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

public class test {

public static void main(String[] args) {

try {

//inFile 作为输入流的数据文件必须存在,否则抛出异常

File inFile = new File("/Users/mumutongxue/Documents/file1.txt");

//file2.txt 没有,系统可以创建,在 workspace 的 Test 项目下可以找到

File outFile = new File("file2.txt");

FileInputStream fis = new FileInputStream(inFile);

FileOutputStream fos = new FileOutputStream(outFile);

int c;

while((c = fis.read()) != -1){

fos.write(c);

}

//打开了文件一定要记着关,释放系统资源

fis.close();

fos.close();

}catch(FileNotFoundException e) {

System.out.println("FileStreamsTest:" + e);

}catch(IOException e){

System.err.println("FileStreamTest:" + e);

}

}

}

缓冲流

类BufferedInputStream 和 BufferedOutoutStream 实现了带缓冲的过滤流,它提供了缓冲机制,把任意的I/O流“捆绑”到缓冲流上,可以提高I/O流的读取效率

在初始化时,除了要指定所连接的I/O流之外,还可以指定缓冲区的大小,缺省时是用32字节大小的缓冲区;最优的缓冲区大小以来于主机操作系统、可使用的内存空间以及机器的配置等;一般缓冲区的大小为内存页或磁盘块等的整数倍

BufferedInputStream 的数据成员buf是一个位数组,默认为2048字节,当读取数据来源时例如文件,BufferedInputStream 会尽量将buf填满。当使用read() 方法时,实际上是先读取buf中的数据,而不是直接对数据来源作读取。当buf中的数据不足时,BufferedInputStream 才会再实现给定的InputStream对象的read() 方法,从指定的装置中提取数据。

BufferedInputStream 的数据成员 buf 是一位数组,默认为512字节。当使用write() 方法写入数据时,实际上会先将数据写至buf中,当buf已满时才会实现给定的OutputStream 对象的write() 方法,将buf数据写至目的地,而不是每次都对目的地作写入的动作。

构造方法:

//[ ] 里的内容代表选填

BufferedInputStream(InputStream in [, int size])

BufferedOutputStream(OutputStream out [, int size])

举个例子,将缓冲流与文件流相接

FileInputStream in = new FileInputStream("file.txt");

FileOutputStream out = new FileOutputStream("file2.txt");

//设置输入缓冲区大小为 256 字节

BufferedInputStream bin = new BufferedInputStream(in,256)

BufferedOutputStream bout = new BufferedOutputStream(out,256)

int len;

byte bArray[] = new byte[256];

len = bin.read(bArray); //len 中得到的是实际读取的长度,bArray 中得到的是数据

对于 BufferedOutputStream,只有缓冲区满时,才会将数据真正送到输出流,但可以使用 flush() 方法人为地将尚未填满的缓冲区中的数据送出。

例如方法copy();

public void copy(InputStream in, OutputStream out) throws IOException {

out = new BufferedOutputStream(out, 4096);

byte[] buf = new byte[4096];

int len = in.read(buf);

while (len != -1) {

out.write(buf, 0, len);

len = in.read(buf);

}

//最后一次读取得数据可能不到 4096 字节

out.flush();

}

数据流

接口 DataInput 和 DataOutput,设计了一种较为高级的数据输入输出方式:除了可处理字节和字节数组外,还可以处理 int、float、boolean 等基本数据类型,这些数据在文件中的表示方式和它们在内存中的一样,无须转换,如 read(), readInt(), readByte()...; write(), writeChar(), writeBoolean()... 此外,还可以用 readLine() 方法读取一行信息。

方法 :

方法

返回值

说明

readBoolean()

boolean

readByte()

byte

readShort()

short

readChar()

char

readInt()

int

readLong()

long

readDouble()

double

readFloat()

float

readUnsignedByte()

int

readUnsignedShort()

int

readFunlly(byte[] b)

void

从输入流中读取一些字节,并将它们存储在缓冲区数组b中

reaFully(byte[] b, int off, int len)

void

从输入流中读取len个字节

skipBytes(int n)

int

与InputStream.skip 等价

readUTF()

String

按照UTF-8形式从输入中读取字符串

readLine()

String

按回车(\r)换行(\n)为分隔符读取一行字符串,不完全支持UNICODE

writeBoolean(boolean v)

void

writeByte(int v)

void

writeShort(int v)

void

writeChar(int v)

void

writeInt(int v)

void

writeLong(long v)

void

writeFloat(float v)

void

writeDouble(double v)

void

write(byte[] b)

void

与OutputStream.write 同义

write(byte[] b,int off,int len)

void

与OutputStream.write 同义

write(int b)

void

与OutputStream.write 同义

writeBytes(String s)

void

只输出每个字符的低 8 位;不完全支持 UNICODE

writeChars(String s)

void

每个字符在输出中都占两个字节

数据流类 DataInputStream 和 DataOutputStream 的处理对象除了是字节或字节数组外,还可以实现对文件的不同数据类型的读写;

分别实现了DataInput 和 DataOutput 接口

在提供字节流的读写手段同时,以统一的形式向输入流中写入boolean,int,long,double 等基本数据类型,并可以再次把基本数据类型的值取回来

提供了字符串读写的手段

数据流可以连接一个已经建立好的数据对象,例如网络连接、文件等。数据流可以通过如下方式建立;

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

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

DataInputStream dis = new DataInputStream(fis);

DataOutputStream dos = new DataOutputStream(fos);

接下来我们通过具体的代码,看一看它的用法吧;

import java.io.DataInputStream;

import java.io.DataOutputStream;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

public class DataStream {

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

// TODO Auto-generated method stub

//向文件 a.txt 写入

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

DataOutputStream dos = new DataOutputStream(fos);

try {

dos.writeBoolean(true);

dos.writeByte((byte)123);

dos.writeChar('J');

dos.writeDouble(3.1415926);

dos.writeFloat(2.122f);

dos.writeInt(123);

}

finally {

dos.close();

}

//从文件 a.txt 读出

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

DataInputStream dis = new DataInputStream(fis);

try {

System.out.println("\t" + dis.readBoolean());

System.out.println("\t" + dis.readByte());

System.out.println("\t" + dis.readChar());

System.out.println("\t" + dis.readDouble());

System.out.println("\t" + dis.readFloat());

System.out.println("\t" + dis.readInt());

}

finally {

dis.close();

}

}

}

标准流、内存读写流、顺序输入流

标准流

语言包 java.lang 中的System类管理标准输入/输出流和错误流

System.in 从InputStream中继承而来,用于从标准输入设备中获取输入数据(通常是键盘)

System.out 从PrintStream 中继承而来,把输入送到缺省的显示设备(通常是显示器)

System.err 也是从PrintStream中继承而来,把错误信息送到缺省的显示设备(通常是显示器)

每当mian方法被执行时,就会自动生产上述三个对象。这里就不再写代码验证了。

内存读写流

为了支持在内存上的I/O,java.io 中提供了类;ByteArrayInputStream、ByteArrayOutputStream 和 StringBufferInputStream

ByteArrayInputStream 可以从指定的字节数组中读取数据

ByteArrayOutputStream 中提供了 缓冲区可以存放数据(缓冲区大小可以在构造方法中设定,缺省为32),可以用write() 方法 向其中写入数据,然后用toByArray() 方法将缓冲区中的有效字节写到字节数组中去。size() 方法可以知道写入的字节数; reset() 可以丢弃所有内容

StringBufferInputStream 与 ByteArrayInputStream 相类似,不同点在于它是从字符缓冲区 StringBuffer 中读取 16位的 Unicode 数据,而不是 8 位的字节数据(已被StringReader取代)

这里只做简要的介绍,有兴趣的同学可以查看一下这些类里具体的方法。

顺序输入流

java.io 中提供了类SequenceInputStream, 使应用程序可以将几个输入流顺序连接起来。顺序输入流提供了将多个不同的输入流统一为一个输入流的功能,这使得程序可能变得更加简洁

例如:

FileInputStream f1,f2;

String s;

f1 = new FileInputStream("file1.txt");

f2 = new FileInputStream("file2.txt");

SequenceInputStream fs = new SequenceInputStream(f1,f2);

DataInputeStream ds = new DataInputStream(fs);

while((s = ds.readLine()) != null) {

System.out.println(s);

}

参考连接

 类似资料: