解析一个小端二进制文件,填充到一个矩阵中

2024-04-07

我有一个包含 X × X 矩阵的二进制文件。文件本身是一个单精度浮点数(小端)序列。我想做的就是解析它,并将其填充到一些合理的 clojure 矩阵数据类型中。

谢谢这个问题 https://stackoverflow.com/questions/749871/how-to-parse-binary-files-in-clojure,我发现我可以用光泽度来解析二进制文件。我现在的代码如下所示:

(ns foo.core
  (:require gloss.core)
  (:require gloss.io)
  (:use [clojure.java.io])
  (:use [clojure.math.numeric-tower]))

(gloss.core/defcodec mycodec
  (gloss.core/repeated :float32 :prefix :none))

(def buffer (byte-array (* 1200 1200)))

(.read (input-stream "/path/to/binaryfile") buffer)

(gloss.io/decode mycodec buffer)

这需要一段时间才能运行,但最终会转储出一大串数字。不幸的是,这些数字都是错误的。经过进一步调查,这些数字被读取为大端字节序。

假设有某种方法可以将这些二进制文件作为小端读取,我想将结果填充到一个矩阵中。这个问题 https://stackoverflow.com/questions/1674335/clojure-matrix-representation似乎已经决定使用 Incanter 及其 Parallel Colt 表示形式,但是,这个问题来自 09 年,我希望坚持使用 clojure 1.4 和 lein 2。在我疯狂的谷歌搜索中,我看到了其他使用 jblas 的建议或象夫。如今有 clojure 的“最佳”矩阵库吗?

EDIT:读取二进制文件非常接近。多亏了这个方便蔚来包装器 https://github.com/pjstadig/nio,我能够获得一个内存映射字节缓冲区作为短单行,甚至可以重新排序:

(ns foo.core
  (:require [clojure.java.io :as io])
  (:require [nio.core :as nio])
  (:import [java.nio ByteOrder]))

(def buffer (nio/mmap "/path/to/binaryfile"))

(class buffer) ;; java.nio.DirectByteBuffer

(.order buffer java.nio.ByteOrder/LITTLE_ENDIAN)
;; #<DirectByteBuffer java.nio.DirectByteBuffer[pos=0 lim=5760000 cap=5760000]>

但是,在不执行中间 (def) 步骤的情况下重新排序会失败:

(.order (nio/mmap f) java.nio.ByteOrder/LITTLE_ENDIAN)

;; clojure.lang.Compiler$CompilerException: java.lang.IllegalArgumentException: Unable to resolve classname: MappedByteBuffer, compiling:(/Users/peter/Developer/foo/src/foo/core.clj:12)
;;  at clojure.lang.Compiler.analyzeSeq (Compiler.java:6462)
;;     clojure.lang.Compiler.analyze (Compiler.java:6262)
;; etc...

我希望能够在函数内部创建重新排序的字节缓冲区,而无需定义全局变量,但现在似乎不是这样。

另外,一旦我重新排序,我不完全确定如何处理我的 DirectByteBuffer,因为它似乎不可迭代。也许对于读取此缓冲区对象(进入 JBLAS 矩阵)的剩余步骤,我将创建第二个问题。

EDIT 2:我将下面的答案标记为已接受,因为我认为我原来的问题结合了太多的东西。一旦我弄清楚了剩下的部分,我将尝试用完整的代码来更新这个问题,该代码从此 ByteBuffer 开始并读入 JBLAS 矩阵(这似乎是正确的数据结构)。

如果有人感兴趣,我可以创建一个返回正确排序的字节缓冲区的函数,如下所示:

;; This works!
(defn readf [^String file]
  (.order
   (.map
    (.getChannel
     (java.io.RandomAccessFile. file "r"))
    java.nio.channels.FileChannel$MapMode/READ_ONLY 0 (* 1200 1200))
   java.nio.ByteOrder/LITTLE_ENDIAN))

我发现的 nio 包装器看起来简化/美化了很多,但看起来我要么没有正确使用它,要么有问题。回顾一下我对 nio 包装器的发现:

;; this works
(def buffer (nio/mmap "/bin/file"))
(def buffer (.order buffer java.nio.ByteOrder/LITTLE_ENDIAN))
(def buffer (.asFloatBuffer buffer))

;; this fails
(def buffer
  (.asFloatBuffer
   (.order
    (nio/mmap "/bin/file")
    java.nio.ByteOrder/LITTLE_ENDIAN)))

遗憾的是,这将是另一天的 clojure 之谜,或者可能是另一个 StackOverflow 问题。


Open a FileChannel(),然后获取内存映射缓冲区。网上有很多关于此步骤的教程。

通过调用将缓冲区的顺序切换为小端order(endian-ness)(不是无参数版本order)。最后,提取浮点数的最简单方法是调用asFloatBuffer()并使用生成的缓冲区来读取浮点数。

之后,您可以将数据放入您需要的任何结构中。

edit以下是如何使用 API 的示例。

;; first, I created a 96 byte file, then I started the repl
;; put some little endian floats in the file and close it
user=> (def file (java.io.RandomAccessFile. "foo.floats", "rw"))
#'user/file
user=> (def channel (.getChannel file))
#'user/channel
user=> (def buffer (.map channel java.nio.channels.FileChannel$MapMode/READ_WRITE 0 96))
#'user/buffer
user=> (.order buffer java.nio.ByteOrder/LITTLE_ENDIAN)
#<DirectByteBuffer java.nio.DirectByteBuffer[pos=0 lim=96 cap=96]>
user=> (def fbuffer (.asFloatBuffer buffer))
#'user/fbuffer
user=> (.put fbuffer 0 0.0)
#<DirectFloatBufferU java.nio.DirectFloatBufferU[pos=0 lim=24 cap=24]>
user=> (.put fbuffer 1 1.0)
#<DirectFloatBufferU java.nio.DirectFloatBufferU[pos=0 lim=24 cap=24]>
user=> (.put fbuffer 2 2.3)
#<DirectFloatBufferU java.nio.DirectFloatBufferU[pos=0 lim=24 cap=24]>
user=> (.close channel)
nil

;; memory map the file, try reading the floats w/o changing the endianness of the buffer
user=> (def file2 (java.io.RandomAccessFile. "foo.floats" "r"))
#'user/file2
user=> (def channel2 (.getChannel file2))                                                
#'user/channel2
user=> (def buffer2 (.map channel2 java.nio.channels.FileChannel$MapMode/READ_ONLY 0 96))
#'user/buffer2
user=> (def fbuffer2 (.asFloatBuffer buffer2))
#'user/fbuffer2
user=> (.get fbuffer2 0)
0.0
user=> (.get fbuffer2 1)
4.6006E-41
user=> (.get fbuffer2 2)
4.1694193E-8

;; change the order of the buffer and read the floats    
user=> (.order buffer2 java.nio.ByteOrder/LITTLE_ENDIAN)                                 
#<DirectByteBufferR java.nio.DirectByteBufferR[pos=0 lim=96 cap=96]>
user=> (def fbuffer2 (.asFloatBuffer buffer2))
#'user/fbuffer2
user=> (.get fbuffer2 0)
0.0
user=> (.get fbuffer2 1)
1.0
user=> (.get fbuffer2 2)
2.3
user=> (.close channel2)
nil
user=> 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

解析一个小端二进制文件,填充到一个矩阵中 的相关文章

随机推荐

  • 如何设置androidcamera2预览和拍摄尺寸?

    我正在使用一个SurfaceView显示我捕获的预览 我想使用 width 1080 height 1920 进行预览 在哪里可以设置预览的大小 我用谷歌搜索答案 但它们都是针对相机版本一的 我正在使用 android hardware c
  • 使用c#备份和恢复Azure sql数据库

    我想将 Azure sql 数据库备份到本地系统 然后在 C 中将该备份恢复到 Azure sql 数据库 任何人都可以帮助我吗 可以这样做吗 Azure SQL 数据库不支持按需创建 bak 文件 Azure SQL 数据库自动备份所有数
  • 如何仅在一个事务中禁用 PostgreSQL 触发器?

    我需要在事务中临时禁用一个 PostgreSQL 触发器 但不需要硬锁定表 有人知道这是否可能吗 像这样的事情 无需锁定表并禁用此事务之外的触发器 BEGIN TRANSACTION ALTER TABLE foo DISABLE TRIG
  • 在 Perl 中处理美元计算的最佳技术是什么?

    在 Perl 中处理美元计算的最佳技术是什么 特别是 以下需要工作 balance 10 payment balance 3 Each payment should be 3 33 How best to round amount bala
  • C#:“Pretty”类型名称函数?

    对于泛型类型 System Type 类的名称属性会返回一个奇怪的结果 有没有办法以更接近我指定的方式获取类型名称 例子 typeof List
  • 在 Swift 上委托 Objective-C 协议

    我正在使用 Swift 语言在 iOS 上实现 UDP 侦听器 为此 我正在转述CocoaAsyncSocket https github com robbiehanson CocoaAsyncSocket项目 我成功地使用 Bridgin
  • 在 C++ 中使用 pthread

    我在用pthread h in a cc文件 当我尝试使用时pthread exit 0 or pthread join mythrds yy NULL 它说 cc text 0x3e undefined reference to pthr
  • 无法使用 Server.MapPath

    我必须做什么才能做到Server MapPath work I have using System Web 还有什么 当我打字时Server没有快速结果选项 智能感知 Server 有什么帮助吗 你可以尝试使用这个 System Web H
  • 如何在 Objective-C 中对 URL 进行编码或解码

    有没有类似的东西 NSString URLencode NSString someString NSString URLdecode NSString someString 如果可以 如何实施 请注意投反对票的人 这不是一个简单的问题 我需
  • Code-golf:将乘法表输出到控制台

    Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的答案或互动 我最近向一位从事工作经验的学生推荐了一篇有关将乘法表转储到控制台的文章 它使用嵌套的 for
  • 雅虎财经历史数据下载网址无效

    我使用以下网址从雅虎财经获取历史数据 从 2017 年 5 月 16 日起 该网址已失效 好像他们已经更改了网址 新网址是 在上面更改的 URL 中有一个会话 cookie 它是碎屑 有什么想法如何以编程方式获取此cookie 在JAVA中
  • 无法通过api在材质表react中获取数据

    我正在尝试通过 Material React 表中的 api 获取数据 但它向我显示错误 如下所示 无效的挂钩调用 钩子只能在函数组件的主体内部调用 发生这种情况可能是由于以下原因之一 1 您的React和渲染器版本可能不匹配 例如Reac
  • 文本框文本在文本输入时消失

    基本上我有一个创建的用户窗体 我想知道是否可以添加用户窗体加载时存在的灰色文本 但一旦用户开始在文本框中输入文本 该文本就会消失 图片已过期 一旦用户开始输入 字体颜色应更改为黑色 任何帮助 将不胜感激 像这样的东西吗 Private Su
  • Kotlin Foo::class.java“未解析的参考:Java”错误

    我正在尝试将我的 Java 代码转换为HomePage class到科特林 我正在按照以下说明进行操作Kotlin org https kotlinlang org docs reference java interop html 获取类
  • SetCursorPos 无法通过远程桌面工作(从 WM_INPUT 事件读取)

    当读取鼠标位置时WM INPUT事件 并且鼠标光标被隐藏 看起来SetCursorPos通过远程桌面使用该应用程序时不起作用 当应用程序不通过远程桌面使用时 相同的代码可以正常工作 即我可以在所有方向上进行无限的鼠标移动 因为SetCurs
  • 如何使用 Bot Framework 在 Teams 中添加提及以及自适应卡

    我正在尝试发送带有自适应卡片附件的活动 并提及创建该帖子的用户 通过在线阅读 我发现您目前无法在自适应卡片中包含提及内容 有没有办法在发送活动时提及某人 例如在另一个附件中 我尝试设置activity Text 提及 这有效 但是它创建了两
  • Google Geocharts:同一地图上的区域和标记?

    我正在尝试使用谷歌地理图表 https google developers appspot com chart interactive docs gallery geochart 我有州数据和城市数据 我想在城市数据上显示它们 这意味着我想
  • 如何获取两个 git 分支之间不同提交的列表?

    我想查看两个分支之间仅非常见提交的列表 我怎样才能得到这样的输出 基本上是一个git diff y master new feature两个分支之间的总结 master new feature xxx Jan 1st 2018 initia
  • 呼叫其他代码呆子 - 嵌套循环的替代方案?

    对于我 或可能其他人 来说 拥有一个需要迭代的对象列表 然后与属性列表进行交互的情况并不罕见 我使用嵌套循环 如下所示 IList
  • 解析一个小端二进制文件,填充到一个矩阵中

    我有一个包含 X X 矩阵的二进制文件 文件本身是一个单精度浮点数 小端 序列 我想做的就是解析它 并将其填充到一些合理的 clojure 矩阵数据类型中 谢谢这个问题 https stackoverflow com questions 7