【问题标题】:Can we read an object serialized in .NET in a linux machine?我们可以在 linux 机器上读取 .NET 中序列化的对象吗?
【发布时间】:2010-12-17 14:47:24
【问题描述】:

我需要将一些以序列化形式编写的文件作为 Windows 机器(C#.NET 序列化)中的文件传输到 linux 机器。我怎样才能做到这一点?我最好在linux端使用perl/Java/bash。

编辑:为了更清楚,文件是文本文件。但在 .NET 中是二进制序列化的。在 linux 端,我需要使用 Perl/Java/Bash 来反序列化和读取这些文件。我有不能触及.NET端代码的限制。我所做的任何事情都必须在linux端..

谢谢,

【问题讨论】:

  • 你的问题不是很清楚;什么样的文件?什么样的数据?你需要使用 perl/java/bash 做什么?
  • 谢谢,更新了问题..
  • 这不是很清楚...您使用哪种序列化?二进制? XML ?
  • 用java序列化,用java反序列化,这是什么问题?
  • 哦抱歉……这是二进制序列化……我的错

标签: c# java .net serialization


【解决方案1】:

如果您有 .NET CLI 实现,例如 MonoDotGNU,您可以在 Linux 上反序列化 .NET 序列化数据。这样,您就可以编写一个 C# 包装器来处理反序列化,然后,正如 Brian 上面所说,如果您想在非 .NET 应用程序中使用数据,则使用 XML 重新序列化。

对于 .NET,必要的命名空间和类是:

BinaryFormatter 和 FileStream 类:

System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
System.IO.FileStream

要反序列化,请创建 BinaryFormatter 和 FileStream 类的实例,将序列化的数据加载到 FileStream 中。然后在 BinaryFormatter 上调用 Deserialize 并转换为必要的数据类型(我在下面将其称为 TheClass):

BinaryFormatter formatter = new BinaryFormatter();
FileStream file = File.OpenRead(@"InsertFileName");
TheClass classInstance = (TheClass)formatter.Deserialize(file);
file.Close();

使用原始 XML 或 SOAP 的 XML 序列化与非 .NET 应用程序的互操作性更高。可以使用 SoapFormatter 类进行 SOAP 序列化:

System.Runtime.Serialization.Formatters.Soap.SoapFormatter

通过创建 FileStream 和 SoapFormatter 实例并调用 Soapformatter Serialize 方法来执行序列化。序列化上面的 classInstance 示例:

FileStream file = File.Create(@"InsertFileName");
SoapFormatter formatter = new SoapFormatter();
formatter.Serialize(file, classInstance);
file.Close();

原始 XML 序列化是高度可定制的,但工作方式略有不同。 XMLSerializer 类用于此目的:

System.Xml.Serialization.XmlSerializer

要使用 XML 序列化来序列化 TheClass,您需要 XmlSerializer 和 StreamWriter 的实例(在 System.IO 中):

XmlSerializer serializer = new XmlSerializer(typeof(TheClass));
StreamWriter xmlFile = new StreamWriter(@"InsertFileName");
serializer.Serialize(xmlFile, classInstance);
xmlFile.Close();

一旦使用 XML,无论是原始语言还是 SOAP,其他语言(如 Java)在阅读它们时应该没有什么困难。有关 XML 序列化的更多信息,请参阅 MSDN 上的this page

为了在 Linux 上使用 .NET,Mono 项目创建了一个名为 MonoDevelop 的 IDE,它的工作方式类似于 Windows 上的 Visual Studio。

希望这些信息有用!

【讨论】:

  • 哦 - 忘了提到您需要在 C# 包装器和目标语言中创建 TheClass 的实现。如果 TheClass 包含在 Windows 上的 DLL 中,则可以在 Linux 上与 Mono 或 DotGNU 一起使用,从而在 C# 包装器中简化此过程。但是请注意,这不适用于目标语言 - 需要为此构建一个实现。
  • 谢谢 Hazel,我想我们可以试试这个。你用过Mono吗?设置和运行有多容易?是不是很稳定?
  • 根据我的经验,Mono 很容易设置和运行。我花了不到一天的时间(不知道自己在做什么,也从未使用过 Mono)来设置 Mono 并将现有的 Winforms 项目移植到 Mono,以便它能够编译和运行。它的性能很糟糕(Mono + Windows Forms = Pain),但我怀疑你会遇到同样的问题。我在 OSX 上,但我怀疑它和 Linux 设置之间的难度差异很大。
  • 欢迎您!是的 - 我同意,Mono 易于设置和运行。据我所知,它预装在 Ubuntu 上,可以轻松安装在 SUSE、Debian、Fedora 等平台上。我不确定稳定性,但根据我的经验,它几乎没有遇到任何问题。
【解决方案2】:

即使你不能接触 .Net 代码,你仍然可以通过编写一个简单的 .Net 程序来解决这个问题,该程序将一个序列化对象作为输入并给出一个重新序列化对象作为输出(使用更容易的序列化读取,例如 XML)。如果这不切实际,您将经历痛苦。我不知道可以读取 windows .Net 二进制序列化文件的 Linux 包装器,尽管 Mono 可能知道如何做到这一点。

如果您想自己动手,您可能会发现 Lluis Sanchez Gual 的 page 是记录其工作原理的有用开始,尽管它是一个旧页面。

【讨论】:

  • 好主意,将其包装并以您知道可行的格式进行序列化
  • 谢谢布赖恩,这就是我们正在做的……将其转换为 XML 序列化并在另一端使用 Java 读取。但也有人担心 windows 端过载(它是一个高负载服务器)
【解决方案3】:

序列化包含足够的信息来提取相应的对象并用日期填充它们。

对于 simple 对象,您可以模拟反序列化过程,但没有什么可以帮助您这样做。您需要自己实现所有内容。

【讨论】:

    猜你喜欢
    • 2020-09-19
    • 2014-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-30
    • 1970-01-01
    • 1970-01-01
    • 2012-05-31
    相关资源
    最近更新 更多