将集合写入二进制文件

时间:2016-05-03 09:22:22

标签: python scala binaryfiles

我正在寻找将一些数据(ListArray等)写入二进制文件的方法。放入二进制文件的集合表示一个点列表。我到现在为止所做的尝试:                                                                                                                                                                                                                                                             [

11:17]
Welcome to Scala 2.12.0-M3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_40).
Type in expressions for evaluation. Or try :help.

scala> import java.io.{FileInputStream, FileOutputStream, ObjectInputStream, ObjectOutputStream}
import java.io.{FileInputStream, FileOutputStream, ObjectInputStream, ObjectOutputStream}

scala> val oos = new ObjectOutputStream(new FileOutputStream("/tmp/f1.data"))
oos: java.io.ObjectOutputStream = java.io.ObjectOutputStream@13bc8645

scala> oos.writeObject(List(1,2,3,4))

scala> oos.close

scala> val ois = new ObjectInputStream(new FileInputStream("/tmp/f1.data"))
ois: java.io.ObjectInputStream = java.io.ObjectInputStream@392a04e7

scala> val s : List[Int] = ois.readObject().asInstanceOf[List[Int]]
s: List[Int] = List(1, 2, 3, 4)

好的,它运作良好。问题是明天我可能需要用另一种语言Python来读取这个二进制文件。是否可以使用多种语言读取更通用的二进制文件?

解决方案

对于在相同情况下搜索的人,你可以这样做:

def write2binFile(filename : String, a : Array[Int]) = {
      val inChannel = new RandomAccessFile(filename, "rw").getChannel
      val bbufer = ByteBuffer.allocateDirect(a.length * 4)
      val ibuffer = bbufer.asIntBuffer()
      ibuffer.put(a)
      inChannel.write(bbufer)
      inChannel.close
    }

1 个答案:

答案 0 :(得分:-1)

跨平台共享点坐标的格式,允许RANGE选择性访问

您的要求是:

  • 通过Scala存储数据,由Python(或其他语言)读取
  • 数据是点坐标列表
  • 将数据存储在AWS S3上
  • 仅允许使用RANGE请求获取部分数据

要使用的数据结构

每个元素的数据结构和大小必须一致,以便通过RANGE计算某个部分的位置。

如果用于存储列表/数组的Scala格式满足此要求,以及是否满足此要求 二进制格式定义得很好,你可能会成功。如果没有,你必须找到 另一种格式。

通过Python读取二进制数据

假设格式已知,请使用stdlib中的Python struct模块来读取它。

替代方法:将数据拆分为较小的部分

您愿意逐个访问数据,可能期望S3上的一个大对象并使用RANGE的HTTP请求。

替代解决方案是将数据拆分为更小的部分,这些部分具有合理的读取大小(例如64 kB,但您知道更好的用例),以及用于在AWS S3上逐个存储它们的设计规则。您甚至可以使用树结构来实现此目的。

这种方法有一些优点:

  • 使用您喜欢的任何格式,例如XML,JSON,无需处理特殊的二进制格式
  • 件可以压缩,您可以节省一些费用

请注意,AWS S3不仅会向您收取数据传输费用,还会向您收取费用,因此使用RANGE的每个HTTP请求都将计为一个。

要考虑的跨平台二进制格式

请考虑以下格式:

  • BSON
  • (Google)结果缓冲区
  • HDF5

如果您访问任何这些格式的维基百科页面,您会发现许多其他格式的链接。

无论如何,我不知道任何这样的格式,每个元素使用统一的大小,因为大多数格式都试图保持尽可能小的大小。因此,除非引入一些特殊的索引文件(可能不太可行),否则不能在使用RANGE的场景中使用它们。

另一方面,使用这些格式与替代方法(分裂 数据到较小的部分)应该有效。

注意:我在过去做了一些关于存储效率和编码/解码速度的测试。从实际的角度来看,使用简单的JSON结构(可能是压缩的)实现了最佳结果。你在每个平台上都能找到这些选项,它使用起来非常简单,编码/解码速度很快(我不说最高)。