java byte二进制输出_Java 基于字节的IO Byte Based IO 二进制格式

更多 Java IO & NIO方面的文章,请参见文集《Java IO & NIO》

FileInputStream & FileOutputStream

读写格式:按字节读写,每次读写一个字节,或者读写一个字节数组。

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

InputStream fin = new FileInputStream("a.txt");

OutputStream fout = new FileOutputStream("b.txt");

System.out.println("How many bytes? = " + fin.available());

int c;

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

System.out.print((char) c);

fout.write(c);

}

}

输出:

How many bytes? = 12

Hello

World

使用缓冲流 BufferedInputStream & BufferedOutputStream

读写格式:按字节读写,每次读写一个字节,或者读写一个字节数组。

优势:使用缓冲流,更节省时间,减少访问磁盘的数目

缓冲区默认大小为 8M:private static int DEFAULT_BUFFER_SIZE = 8192;

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

InputStream fin = new FileInputStream("a.txt");

BufferedInputStream bin = new BufferedInputStream(fin);

OutputStream fout = new FileOutputStream("b.txt");

BufferedOutputStream bout = new BufferedOutputStream(fout);

System.out.println("How many bytes? = " + bin.available());

// Read and Write by byte

int c;

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

System.out.print((char) c);

bout.write(c);

}

// Read and Write by byte array

byte[] buf = new byte[12];

while (bin.read(buf) != -1) {

for(byte b: buf)

System.out.print((char) b);

bout.write(buf);

}

}

输出:

How many bytes? = 12

Hello

World

FileInputStream VS BufferredInputStream

对比以上两个例子:

一个使用 FileInputStream 来操作文件

另外一个使用 BufferredInputStream 来封装 FileInputStream,然后操作文件。效率更高!!!

原因分析:

FileInputStream 的 read 方法实现如下:

可以看出,实际上调用了一个本地方法,每次读取一个字节,都需要通过 OS 来访问磁盘。

/**

* Reads a byte of data from this input stream. This method blocks

* if no input is yet available.

*

* @return the next byte of data, or -1 if the end of the

* file is reached.

* @exception IOException if an I/O error occurs.

*/

public int read() throws IOException {

return read0();

}

private native int read0() throws IOException;

BufferedInputStream 的 read 方法实现如下:

可以看出,BufferedInputStream 有一个缓冲区,每次从磁盘中读取 8M 的字节,存储到内存缓冲区中,调用 read() 时实际上是读取缓冲区,无需访问磁盘。

public synchronized int read() throws IOException {

if (pos >= count) {

fill();

if (pos >= count)

return -1;

}

return getBufIfOpen()[pos++] & 0xff;

}

读取具体数据类型 DateInputStream & DateOutputStream

读写格式:按字节读写,按照具体的数据类型读写特定数目的字节:

readChar, writeChar:每次读写 2 个字节

public final char readChar() throws IOException {

int ch1 = in.read();

int ch2 = in.read();

if ((ch1 | ch2) < 0)

throw new EOFException();

return (char)((ch1 << 8) + (ch2 << 0));

}

public final void writeChar(int v) throws IOException {

out.write((v >>> 8) & 0xFF);

out.write((v >>> 0) & 0xFF);

incCount(2);

}

readInt, writeInt:每次读写 4 个字节

public final int readInt() throws IOException {

int ch1 = in.read();

int ch2 = in.read();

int ch3 = in.read();

int ch4 = in.read();

if ((ch1 | ch2 | ch3 | ch4) < 0)

throw new EOFException();

return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));

}

public final void writeInt(int v) throws IOException {

out.write((v >>> 24) & 0xFF);

out.write((v >>> 16) & 0xFF);

out.write((v >>> 8) & 0xFF);

out.write((v >>> 0) & 0xFF);

incCount(4);

}

readDouble, writeDouble:每次读写 8 个字节

readLong, writeLong:每次读写 8 个字节

...

DateInputStream & DateOutputStream 的使用:

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

OutputStream fout = new FileOutputStream("chars.txt");

DataOutputStream dout = new DataOutputStream(fout);

char chars[] = {'A', 'B', 'C', 'D'};

for (int c : chars) {

dout.writeChar(c);

}

dout.flush();

InputStream fin = new FileInputStream("chars.txt");

DataInputStream din = new DataInputStream(fin);

char c;

while (din.available() > 0) {

c = din.readChar();

System.out.print(c);

}

}

输出:

ABCD

注意事项:

如下代码会将 1 按照二进制形式写入文件中,占据 4 bytes。

因此用记事本打开该文本文件,其实无法看到数字 1。

int i = 1;

dout.writeInt(i);

读取对象 ObjectInputStream & ObjectOutputStream

读写格式:按字节读写,读写的对象需要实现 Serializable 接口。

ObjectInputStream & ObjectOutputStream 的使用:

public class Stream_Object_Test {

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

OutputStream fout = new FileOutputStream("people.txt");

ObjectOutputStream oout = new ObjectOutputStream(fout);

People p = new People("Tom", 20);

oout.writeObject(p);

InputStream fin = new FileInputStream("people.txt");

ObjectInputStream oin = new ObjectInputStream(fin);

People new_p = (People) oin.readObject();

System.out.println(new_p.getName() + " " + new_p.getAge());

}

}

class People implements Serializable {

private String name;

private int age;

People(String name, int age) {

this.name = name;

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值