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