C# 和 Android/Java - 跨语言二进制流编写器/读取器? (对于原语和 UTF-8 字符串)

发布于 2024-12-02 03:56:10 字数 397 浏览 2 评论 0原文

在 C# 和 Android 的 Java 之间对某些自定义数据进行二进制序列化/反序列化的最简单方法是什么?我想为 Java 找到类似于 C# BinaryWriter 和 BinaryReader 的东西 - 它支持编写原语(如 uint16)和 UTF-8 字符串。

或者也许有更好的方法?

编辑:编译时不知道数据的结构

示例写入:

        BinaryWriter w = new BinaryWriter(File.OpenWrite(@"D:\data"));
        w.Write((UInt16)1234);
        w.Write("To jest żółwiątko");
        w.Write((UInt16)4567);

What is the easiest way to do binary serialization/deserialization of some custom data between C# and Android's Java? I'd like to find for Java something similar to C# BinaryWriter and BinaryReader - which supports writing primitives (like uint16) and UTF-8 strings.

Or maybe there is a better way?

edit: structure of the data is not know at compilation time

Sample write:

        BinaryWriter w = new BinaryWriter(File.OpenWrite(@"D:\data"));
        w.Write((UInt16)1234);
        w.Write("To jest żółwiątko");
        w.Write((UInt16)4567);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

近箐 2024-12-09 03:56:10

在 Java 中,所有原始类型都是有符号的(奇怪的是,甚至是字节!)。因此,如果您想使用 DataInputStream.readInt()。另请注意,readInt() 使用大端字节序。您可以使用 Jon Skeets MiscUtils 的 EndianBinaryReader 之类的东西来编写这些内容,以便可以在安卓上阅读。

UTF-8 有点棘手,因为 DataInputStream 使用称为 MUTF-8(修改版 UTF-8)的字符串编码。在我们用来在 android 和 .net 之间共享数据的代码中,我们使用简单的游程编码的 UTF-8 字节来表示字符串(-1 为空)。我们在 Java 中的 reader 方法看起来像这样,从 C# BinaryWriter 读取标准 UTF-8 编码的字符串(在第一次写出 Int16 长度之后):

public String readUTF8String() throws ImageFileFormatException, IOException
 {
     short len = readInt16();
     if (len == -1)
         return null;
     if (len == 0)
         return "";
     if (len < -1)
         throw new ImageFileFormatException("Invalid UTF8 string");
     byte[] utf8Bytes = readBytes(len);
     return new String(utf8Bytes, "UTF-8");
 }

In Java all primitive types are signed (oddly even byte!). So you will need to write out signed integers if you want to read them in Java using DataInputStream.readInt(). Also note that readInt() uses big-endian. You can use something like the EndianBinaryReader from Jon Skeets MiscUtils to write these so the can be read on Android.

UTF-8 is a little trickier as DataInputStream uses something called MUTF-8 (Modified UTF-8) Encoding for strings. In code that we use to share data between android and .net we use a simple run-length encoded UTF-8 bytes to represent a String (-1 is null). Our reader method in Java looks something like this to read standard UTF-8 encoded strings from the C# BinaryWriter (after first writing out Int16 length):

public String readUTF8String() throws ImageFileFormatException, IOException
 {
     short len = readInt16();
     if (len == -1)
         return null;
     if (len == 0)
         return "";
     if (len < -1)
         throw new ImageFileFormatException("Invalid UTF8 string");
     byte[] utf8Bytes = readBytes(len);
     return new String(utf8Bytes, "UTF-8");
 }
别低头,皇冠会掉 2024-12-09 03:56:10

这些库是否满足您的需求?:

  • 协议缓冲区 - “协议缓冲区是一种以高效且可扩展的格式对结构化数据进行编码的方法。Google 几乎所有内部​​ RPC 协议和文件格式都使用协议缓冲区。”

  • Apache Thrift - “Thrift 是一个用于可扩展跨语言服务开发的软件框架。它结合了一个软件与代码生成引擎堆栈,以构建在 C++、Java、Python、PHP、Ruby、Erlang、Perl、Haskell、C#、Cocoa、JavaScript、Node.js、Smalltalk 和 OCaml 之间高效、无缝工作的服务。”

Do either of these libraries meet your needs?:

  • Protocol Buffers - "Protocol Buffers are a way of encoding structured data in an efficient yet extensible format. Google uses Protocol Buffers for almost all of its internal RPC protocols and file formats."

  • Apache Thrift - "Thrift is a software framework for scalable cross-language services development. It combines a software stack with a code generation engine to build services that work efficiently and seamlessly between C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml."

半衾梦 2024-12-09 03:56:10

几天前我也面临着同样的情况。
这是我的解决方案,试试这个(C#代码):

public static void WriteUTF(this BinaryWriter writer, string s)
{
    short length = (short)Encoding.UTF8.GetByteCount(s);
    writer.Write(BitConverter.GetBytes(length).Reverse().ToArray());
    writer.Write(s.ToCharArray());
}

Some days ago I was facing the same situation.
Here is my solution, try this (C# code):

public static void WriteUTF(this BinaryWriter writer, string s)
{
    short length = (short)Encoding.UTF8.GetByteCount(s);
    writer.Write(BitConverter.GetBytes(length).Reverse().ToArray());
    writer.Write(s.ToCharArray());
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文