【问题标题】:ObjectOutputStream read in other language以其他语言读取的 ObjectOutputStream
【发布时间】:2021-01-11 14:45:09
【问题描述】:

我曾经使用带有 Java 的 Android Studio 在 Android 中保存项目。但现在我想在我用 Flutter SDK(Dart 语言)重写的应用程序中准确地读取这些数据。但似乎编写的文件是非常特定于 Java 的。这是 Java 中的保存和加载方法。

public void save(Item item)
{
    String json = gson.toJson(item);
    FileOutputStream fos = null;
    try {
        fos = context.openFileOutput("item_"+ item.getUid(), Context.MODE_PRIVATE);
        ObjectOutputStream os = new ObjectOutputStream(fos);
        os.writeObject(json);
        os.close();
        fos.close();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}


private Item loadItem(String fileName)
{
    FileInputStream fis = null;
    try {
        fis = context.openFileInput(fileName);
        ObjectInputStream is = new ObjectInputStream(fis);
        Object object = is.readObject();
        Item item = null;
        String json = (String)object;
        item = gson.fromJson(json, Item.class);
        is.close();
        fis.close();
        return item;
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
    return null;
}

现在在 Dart 中阅读它

Uint8List bytes = f.readAsBytesSync();
var data = bytes.buffer.asByteData();
// HOW TO DETECT JAVA
if (?SOMETHING?) { }

bytes 的长度相当大。它是一个长度 = 3 245 500 的数组。 json 字符串的长度应该在 740 到 840 字节之间(即相对较短的 json)。

我怎么能只读取 json 部分而不是整个 Java 'overhead'/'java serialization format'

【问题讨论】:

  • 我建议您阅读 Java 中的数据并切换到序列化为 json、xml 或其他与 Java 没有密切关联的格式。为此使用 Java 序列化是错误的工具,尝试用另一种语言阅读它是非常痛苦的。另外,将某些内容转换为json,然后将该字符串写入ObjectOutputStream,这很奇怪,为什么不直接将json写入FileOutputStream
  • “编写的文件是 Java 特有的” 你是对的。 ObjectOutputStream 用于编写供ObjectInStream 读取的二进制文件(甚至在javadoc 中也这么说),而不是用于与其他语言的一般通信。如果要与其他语言交换数据,则应选择与语言无关的格式,例如 XML 或 JSON。
  • 简而言之,去掉ObjectOutputStream(可以用OutputStreamWriter代替),直接将json写入文件,不用Java的对象序列化格式包装。
  • Mark Rotteveel 是对的,尽管使用十六进制编辑器您可能会发现如何提取 json 部分(UTF-8 字符串)。
  • 问题是Java版本已经发布了一年多,现在要在Flutter中替换应用程序,因此替换旧代码不是一个选项,因为仍然存在需要阅读的旧格式项目

标签: java flutter dart


【解决方案1】:

你目前正在做的是:

  1. 序列化为 JSON
  2. 使用 Java 序列化使用 JSON 数据序列化 Java 字符串

相反,将您的代码更改为:

  1. 序列化为 JSON(直接到文件,或首先到字符串,然后使用 OutputStreamWriter 包装 FileOutputStream 到文件)。

尝试用另一种语言重新实现 Java 序列化是非常痛苦的,而且您当前对 Java 序列化的使用意义不大,而且这是不必要的开销,只会让您的生活更加艰难。将其从组合中删除并将 JSON 直接写入文件。

它将简化您的代码,并且无需在 Dart 中实现 Java 序列化。

为了能够处理以这种 Java 序列化包装 JSON 数据的组合编写的当前文件,我建议在您的 Java 应用程序中使用一些额外的代码来检测文件是否是 Java 序列化,如果是,则一次性转换为直接存储 JSON。

或者,您可以在Java Object Serialization Specification 中阅读 Java 序列化协议。

【讨论】:

  • 我确实注意到我之前所做的完全错误。我以为我只是将文件写入内存,但事实证明我正在做 Java 特定的事情。但该应用程序现在已发送给数千名用户。所以理想情况下,我可以解密 Java 格式并提取字节
  • @WouterVandenpute 我建议发布一个新版本,它将读取序列化文件,然后将其写为普通 JSON,从那时起您可以使用 JSON。我想这会比在 Dart 中实现(部分)Java 反序列化更简单。
猜你喜欢
  • 1970-01-01
  • 2010-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-08
  • 1970-01-01
相关资源
最近更新 更多