Ocaml如何在文件中表示字节?

时间:2016-06-26 22:19:16

标签: hex ocaml bytecode

我正在尝试编写一个函数来将一个字节列表写入一个文件(我们正在编写一个.class文件的解析器,并在一些插入后写回文件。)当我的伙伴编写代码来读取时在它中,字节码列表变量是一个整数列表。所以现在我需要将其转换为字节,然后将其写入新的.class文件。十六进制数的表示是否基本相同,以便JVM可以处理新的.class文件?我的功能编程是三年前的一个学期的LISP和一年前的一个学期的Coq。不足以让我轻易地在功能方面思考。

1 个答案:

答案 0 :(得分:2)

事实上,你的问题非常令人困惑。下面是一些代码,它将文件的字节作为int列表读入,然后将int作为字节写回到新文件中。在一个合理的系统上(你没有提到你的系统),这将完全复制一个文件,这样包括JVM在内的任何程序都无法区分它。

let get_bytes fn =
    let inc = open_in_bin fn in
    let rec go sofar =
        match input_char inc with
        | b -> go (Char.code b :: sofar)
        | exception End_of_file -> List.rev sofar
    in
    let res = go [] in
    close_in inc;
    res

let put_bytes fn ints =
    let outc = open_out_bin fn in
    List.iter (fun b -> output_char outc (Char.chr b)) ints;
    close_out outc

let copy_file infn outfn =
    put_bytes outfn (get_bytes infn)

我在我的系统上测试了这个(OS X 10.11.2)。我没有任何类文件,但是JVM在运行用copy_file复制的jar文件时没有遇到任何问题。

这个问题的本质与十六进制数无关。这些是将数字表示为字符串的方式,它们不会出现在任何地方。它与函数式编程几乎没有关系,除了你想在OCaml中编写代码这一事实。

问题的实质是存储在文件中的一系列字节的含义。在最低级别,存储在文件中的字节是文件的含义。因此,只需复制字节即可忠实地复制文件。这就是copy_file所做的。

由于你想更改字节,你当然需要确保你的新字节代表一个有效的类文件。一旦你想出了你想要的新字节,就可以用put_bytes(在一个合理的系统上)写出来。