我有一个文件,其中包含一个由Data.Binary序列化的[Double]
,我想用C读取它。也就是说,我想编写一个C程序,将该数据读取到内存中作为double[]
。我打算编写一个Haskell程序来反序列化数据文件,然后将二进制数据写入一个新的,更简单的文件,我可以直接读入C,但我不确定如何只写出原始二进制数据(例如双字节为8个字节)。用Haskell写入二进制数据可以被C读取?
回答
使用Data.Binary
来序列化Double
或Float
值对于可移植性来说不是很好。 Binary
实例序列化由decodeFloat
获得的形式的值,即作为尾数和指数。尾数序列号为Integer
。解析不方便。正如eHird已经提出的,更好的是使用一个将它们序列化为IEEE-754表示的位模式的变体,如cereal-ieee754所提供的那样 - 正如ehird提醒的那样,已经合并(减去浮点和单词类型)转换为cereal - 或已经提到的data-binary-ieee754。另一个选项是通过show
将它们序列化为字符串。这具有避免任何字节序问题的优点。
您可以重复使用Data.Binary
用于data-binary-ieee754包,该包允许将序列化Float
s和Double
作为它们的IEEE表示。例如:
import Data.List
import Data.Binary.Put
import Data.Binary.IEEE754
import Control.Monad
putRawDoubles :: [Double] -> Put
putRawDoubles xs = do
putWord64le $ genericLength xs
mapM_ putFloat64le xs
这将是很好,如果有中putWord64host
为Double
S IN数据二进制IEEE754模拟,但由于没有我只是小端去。如果您希望在C程序中无需明确处理转换就可以在字节码之间进行移植,则可以尝试putWord64host . doubleToWord
(doubleToWord
也是从Data.Binary.IEEE754
)。虽然我认为整数字节序在一些平台上不同于浮点字节序列...
顺便提一句,我建议使用这样的格式,即使是你的常规序列化; IEEE浮点是通用的,而二进制的默认浮点格式是浪费的(正如Daniel Fischer所指出的那样)。
您可能还想考虑cereal序列化库,它比二进制更快,保持得更好(二进制文件自2009年以来未更新)并且支持IEEE浮点格式built-in。
有或有几个平台具有不同的浮点和整数字节序。我忘了哪个。但这些野兽太难以担忧了。 –
- 1. 读取和写入pdf或二进制数据在C
- 2. 读取C++中的二进制数据并写入MySQL
- 3. 将二维数组写入/读取二进制文件C++
- 4. C以二进制模式读取/写入文件
- 5. 写入和读取二进制文件以填充矢量 - C++
- 6. 无法使用Node.js读取和写入二进制数据
- 7. C#,写入二进制数据
- 8. 通过C++读取二进制数据
- 9. 如何在C++中将二进制读取/写入转换为非二进制读取/写入
- 10. 写入二进制数据
- 11. 读取二进制数据
- 12. Java二进制IO写入和读取
- 13. 读取和写入二进制文件
- 14. Python的读取和写入二进制
- 15. 读取/写入压缩的二进制数据
- 16. Redis/java - 写入和读取二进制数据
- 17. 如何从PostgreSQL写入/读取二进制数据?
- 18. 读取和写入类数据的二进制文件在VC++
- 19. Android,读取二进制数据并将其写入文件
- 20. 使用C++读取和写入二进制信息
- 21. 使用FileSystemObject写入二进制数据()
- 22. C#WPF二进制读取
- 23. C#二进制读取器
- 24. 我可以简化从二进制数据读取短小
- 25. 我可以通过XDomainRequest正确读取二进制数据吗?
- 26. 如何将二进制数据写入文件以便快速读取?
- 27. 如何使用可以在c中读取的python编写二进制结构?
- 28. 插入器和提取器读取/写入二进制数据与文本
- 29. 读取和写入二进制文件,Fortran和C++
- 30. C#,写入和读取二进制文件中的图像
顺便说一下,谷物ieee754的功能最近合并到谷物本身。 – ehird
啊,谢谢。我忘了。不幸的是,'Word64 <-> Double'和'Word32 <-> Float'转换已被删除,并且它们是我在任一包中感兴趣的唯一东西;) –
是的,如果将这些转换为单独的包序列化库可能依赖于。 – ehird