ZetCode

Java DataOutput 接口

最后修改时间:2025 年 4 月 16 日

java.io.DataOutput 接口提供了以可移植的方式将 Java 原始类型写入输出流的方法。 它支持二进制数据输出操作,将值转换为字节序列。 类实现此接口以支持与机器无关的数据写入。

DataOutputDataOutputStreamRandomAccessFile 等类实现。 它定义了写入所有原始类型和字符串的方法。 数据以大端格式写入,以便在不同平台上实现可移植性。

DataOutput 接口概述

DataOutput 接口包含写入原始类型和字符串的方法。 每种方法以特定的二进制格式写入数据。 该接口确保一致的数据表示,而与底层平台无关。

public interface DataOutput {
    void write(int b) throws IOException;
    void write(byte[] b) throws IOException;
    void write(byte[] b, int off, int len) throws IOException;
    void writeBoolean(boolean v) throws IOException;
    void writeByte(int v) throws IOException;
    void writeShort(int v) throws IOException;
    void writeChar(int v) throws IOException;
    void writeInt(int v) throws IOException;
    void writeLong(long v) throws IOException;
    void writeFloat(float v) throws IOException;
    void writeDouble(double v) throws IOException;
    void writeBytes(String s) throws IOException;
    void writeChars(String s) throws IOException;
    void writeUTF(String s) throws IOException;
}

上面的代码显示了 DataOutput 接口中定义的所有方法。 这些方法允许以与平台无关的方式写入原始类型。 writeUTF 方法对于字符串序列化尤其重要。

使用 DataOutputStream 写入原始类型

DataOutputStreamDataOutput 最常见的实现。 它包装一个输出流,并提供写入原始类型的方法。 此示例演示如何将不同的数据类型写入文件。

Main.java
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        try (DataOutputStream dos = new DataOutputStream(
                new FileOutputStream("data.bin"))) {
            
            // Write various data types
            dos.writeBoolean(true);
            dos.writeByte(65); // 'A'
            dos.writeShort(1000);
            dos.writeInt(123456);
            dos.writeLong(987654321L);
            dos.writeFloat(3.14159f);
            dos.writeDouble(2.71828);
            dos.writeUTF("Hello, DataOutput!");
            
            System.out.println("Data written successfully");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此示例显示了如何使用 DataOutputStream 写入不同的原始类型。 try-with-resources 确保正确的流关闭。 每种写入方法都将值转换为大端格式的字节。 可以使用 DataInputStream 读回该文件。

使用 DataOutput 写入字节数组

DataOutput 接口提供了写入字节数组的方法。 这些方法对于写入原始二进制数据非常有用。 您可以写入整个数组或其中的一部分。

Main.java
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        byte[] data = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
        
        try (DataOutputStream dos = new DataOutputStream(
                new FileOutputStream("bytes.bin"))) {
            
            // Write entire array
            dos.write(data);
            
            // Write portion of array (positions 2-5)
            dos.write(data, 2, 4);
            
            System.out.println("Byte arrays written successfully");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此示例演示了如何使用 DataOutput 方法写入字节数组。 第一次调用写入整个数组,而第二次调用仅写入一部分。 offset 和 length 参数指定要写入的字节。

使用 DataOutput 写入字符串

DataOutput 提供了三种写入字符串的方法:writeByteswriteCharswriteUTF。 每种方法以不同的方式处理字符串数据,其中 writeUTF 是最常用的。

Main.java
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        String text = "Java DataOutput";
        
        try (DataOutputStream dos = new DataOutputStream(
                new FileOutputStream("strings.bin"))) {
            
            // Write as sequence of bytes (loses Unicode info)
            dos.writeBytes(text);
            
            // Write as sequence of chars (2 bytes per char)
            dos.writeChars(text);
            
            // Write in UTF-8 modified encoding
            dos.writeUTF(text);
            
            System.out.println("Strings written in different formats");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此示例显示了使用 DataOutput 写入字符串的不同方法。 writeBytes 仅写入每个字符的低位字节。 writeChars 将每个字符写入为两个字节。 writeUTF 使用紧凑的 UTF-8 修改编码,其中包含长度信息。

将 DataOutput 与 RandomAccessFile 一起使用

RandomAccessFile 实现了 DataOutput,允许随机访问文件写入。 此示例演示了在文件中特定位置写入数据。

Main.java
import java.io.IOException;
import java.io.RandomAccessFile;

public class Main {

    public static void main(String[] args) {
        try (RandomAccessFile raf = new RandomAccessFile("random.bin", "rw")) {
            
            // Write some initial data
            raf.writeInt(100);
            raf.writeDouble(3.14);
            
            // Move to position 20 and write more data
            raf.seek(20);
            raf.writeUTF("Jumped to position 20");
            
            // Return to start and modify first value
            raf.seek(0);
            raf.writeInt(200);
            
            System.out.println("Random access writing complete");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此示例显示了 RandomAccessFile 如何实现 DataOutput 以进行随机访问写入。 seek 方法在写入之前移动文件指针。 这允许修改现有数据或在任意位置写入。

为自定义类实现 DataOutput

您可以在自定义类中实现 DataOutput 以提供二进制输出功能。 此示例显示了一个简单的实现,该实现写入字节数组。

Main.java
import java.io.DataOutput;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;

class ByteArrayDataOutput implements DataOutput {
    private ByteBuffer buffer;
    
    public ByteArrayDataOutput(int size) {
        buffer = ByteBuffer.allocate(size);
    }
    
    @Override
    public void write(int b) throws IOException {
        buffer.put((byte) b);
    }
    
    @Override
    public void write(byte[] b) throws IOException {
        buffer.put(b);
    }
    
    // Other write methods implemented similarly...
    
    public byte[] toByteArray() {
        return Arrays.copyOf(buffer.array(), buffer.position());
    }
}

public class Main {
    public static void main(String[] args) {
        try {
            ByteArrayDataOutput output = new ByteArrayDataOutput(100);
            output.writeInt(42);
            output.writeUTF("Custom DataOutput");
            
            byte[] result = output.toByteArray();
            System.out.println("Wrote " + result.length + " bytes");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此示例演示了使用 ByteBuffer 的自定义 DataOutput 实现。 该类提供基本的写入功能,并将缓冲区转换为字节数组。 真正的实现需要处理所有接口方法。

来源

Java DataOutput 接口文档

在本文中,我们介绍了 Java DataOutput 接口的基本方法和功能。 了解这些概念对于在 Java 应用程序中使用二进制数据输出操作至关重要。

作者

我叫 Jan Bodnar,是一位经验丰富的专业程序员。 我于 2007 年开始撰写编程文章,至今已创作了 1400 多篇文章和八本电子书。 凭借八年多的教学经验,我致力于分享我的知识,帮助他人掌握编程概念。

列出所有Java教程