java - 读/写二进制结构: how to simplify this code?

标签 java coding-style binary-data

我正在编写一个网络应用程序,它发送和接收许多不同类型的二进制数据包,并且我正在尝试尽可能轻松地向我的应用程序添加新类型的数据包。

现在,我创建了一个 Packet 类,并为每种不同类型的数据包创建了它的子类。然而,它并不像看起来那么干净;我最终得到了这样的代码:

static class ItemDesc extends Packet {
    public final int item_id;
    public final int desc_type;
    public final String filename;
    public final String buf;

    public ItemDesc(Type t, int item_id, int desc_type, String filename, String buf) {
        super(t); // sets type for use in packet header
        this.item_id = item_id;
        this.desc_type = desc_type;
        this.filename = filename;
        this.buf = buf;
    }

    public ItemDesc(InputStream i) throws IOException {
        super(i); // reads packet header and sets this.input
        item_id = input.readInt();
        desc_type = input.readByte();
        filename = input.readStringWithLength();
        buf = input.readStringWithLength();
    }

    public void writeTo(OutputStream o) throws IOException {
        MyOutputStream dataOutput = new MyOutputStream();
        dataOutput.writeInt(item_id);
        dataOutput.writeByte(desc_type);
        dataOutput.writeStringWithLength(filename);
        dataOutput.writeStringWithLength(buf);
        super.write(dataOutput.toByteArray(), o);
    }
}

这种方法让我困扰的是代码重复 - 我将数据包结构重复四次。我很高兴避免这种情况,但我看不到简化它的合理方法。

如果我用 Python 编写,我会创建一个包含所有可能字段类型的字典,然后定义新的数据包类型,如下所示:

ItemDesc = [('item_id', 'int'), ('desc_type', 'byte'), ...]

我想我可以用任何函数式语言做类似的事情。但是,我看不到将这种方法应用于 Java 的方法。

(也许我太迂腐了,或者我习惯了函数式编程和写代码的代码,所以我可以避免任何重复:))

预先感谢您的任何建议。

最佳答案

我同意@silky的观点,您当前的代码是一个很好的解决方案。在我看来,一些重复(尽管不是重复)的代码并不是一件坏事。

如果您想要一个更像 python 的解决方案,您可以:

  1. 用某种保留顺序的映射结构替换 ItemDesc 的成员属性,使用迭代映射的通用 writeTo 方法进行序列化。您还需要为每个属性添加 getter,并替换现有字段的所有使用。
  2. 将成员属性替换为 Properties 对象,并使用 Properties 序列化而不是二进制写入。
  3. 编写一个通用的 writeTo 方法,该方法使用 Java 反射来访问成员属性及其类型并序列化它们。

但在所有 3 种情况下,代码都会比当前的“丑陋”代码更慢、更复杂并且可能更脆弱。我不会这样做。

关于java - 读/写二进制结构: how to simplify this code?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1376558/

相关文章:

scala - 在 Scala 的文件中有效地存储 Long 序列

Java/MySQL : Inserting row into table from Java Web Application (TomCat v7. 0)

java - 如何在另一个模块中 Autowiring 服务?

java - 如何在不扩展 fragment 类的情况下使用 getchildfragmentmanager ?

if-statement - 最佳实践 : if logic control

python - Flake 8 与 ESLint max-statements 的等价

纯 C(非 C++)的编码标准

java - 如何在 SocketChannel 关闭时收到通知?

Prolog - 使用 DCG 处理二进制数据

Java二进制文件writeUTF...解释规范