代码之家  ›  专栏  ›  技术社区  ›  qertoip

如何在Clojure中将序列转换为字节[]?

  •  5
  • qertoip  · 技术社区  · 15 年前

    我需要把原始字节写入文件。我是这样做的:

    (.write (FileOutputStream "/path") bytes)
    

    …其中字节必须是byte[]类型。请注意不能是字节[]。

    user=> (bytes (into-array (filter #(not (= % 13)) (to-byte-array (File. "e:/vpn.bat")))))
    java.lang.ClassCastException: [Ljava.lang.Byte; cannot be cast to [B (NO_SOURCE_FILE:0)
    

    继续的:

    字节/类型的into数组工作正常。但是,字节数组没有。文件为空:

    (import 'FileOutputStream)
    (use 'clojure.contrib.io)
    
    (defn remove-cr-from-file [file]
      (with-open [out (FileOutputStream. file)]
        (let [dirty-bytes (to-byte-array file)
              clean-seq   (filter #(not (= 13 %)) dirty-bytes)
              clean-bytes (byte-array clean-seq)]
          (.write out clean-bytes))))
    
    3 回复  |  直到 15 年前
        1
  •  3
  •   Michał Marczyk    15 年前

    更新:问题的新部分(“续”)在接近结尾时得到了回答。


    这个问题实际上说明了一个有趣的观点: -- bytes , ints . 它们只强制转换为目标类型,这特别意味着 必须已经是适当类型的数组。

    int[] long[]

    在Clojure这样的动态语言中,cast之所以有用,与效率(您可以在类型提示旁边使用cast来加快速度)和互操作(在这种情况下,您经常需要一个类型正好合适的东西)有关。编译器不能仅仅推断出正确的数组类型的原因是因为没有足够的信息来这样做(更不用说可能还不清楚“正确”的类型是什么)。

    Byte/TYPE (如解仁所建议)或跳过 into-array 字节 然后把它包起来 filter bytes-array 相反(正如布伦顿·阿什沃思所建议的那样)。


    问题文本中新包含的代码的问题是它打开了一个 FileOutputStream 在读取文件内容之前。打开FOS的动作已经清除了文件:

    (with-open [out (FileOutputStream. some-file)]
      :foo)
    
    ; => :foo
    ; side effect: some-file is now empty
    

    你得从外面的文件里读出来 with-open

    (let [foo (byte-array
               (filter #(not= 13 %)
                       (to-byte-array some-file)))]
      (with-open [out (FileOutputStream. some-file)]
        (.write out foo)))
    
        2
  •  6
  •   Brenton Ashworth    15 年前

    还有字节数组函数。

    如果需要打包字节数组,可以查看 http://github.com/geoffsalmon/bytebuffer

        3
  •  3
  •   Cactus    9 年前
    (into-array Byte/TYPE (filter #(not (= % 13)) (.getBytes (slurp "e:/vpn.bat"))))
    

    如果您不介意使用字符串作为中介,尽管我认为您可以替换 .getBytes to-byte-array

    我想问题是 (bytes) 需要基元类型数组。如果你不指定 (into-array) ,它将返回装箱类型。

    推荐文章