gratifiant > comp.lang.* > comp.lang.caml

toucan (20/03/2010, 14h23)
Bonjour,

J'essaie de lire un fichier binaire dans une chaîne de caractère,
à l'aide de la fonction Unix.read. Elle semble renvoyer au
maximum 16384 à la fois. J'aimerais savoir d'où vient cette limite
(imposée par l'OS ou par ocaml ?).
La doc "man 2 read" m'indique que ce n'est pas a priori une erreur,
mais il me semble qu'en C on peut lire plus que ça en une fois.

J'utilise ocaml 3.11.2 sous Linux Debian 5, 32 bits.

Pour observer la chose, on peut utiliser :

open Unix;;

let check name =
let n = (stat name).st_size in
let s = String.make n ' ' in
let fd = openfile name [O_RDONLY] 0o600 in
let k = read fd s 0 n in
close fd;
k;;

Ce n'est de toute façon pas bien grave, puisqu'il suffit d'écrire
une boucle qui lit tout, ce qui est plus propre.

let readbytes name =
let n = (stat name).st_size in
let s = String.make n ' '
and ofs = ref 0
and fd = openfile name [O_RDONLY] 0o600 in
while !ofs < n do
ofs := !ofs + read fd s !ofs (n - !ofs)
done;
close fd;
s;;
Blue Prawn (22/03/2010, 02h01)
toucan wrote:

> Bonjour, Bonjour,


> J'essaie de lire un fichier binaire dans une chaîne de caractère,
> à l'aide de la fonction Unix.read. Elle semble renvoyer au
> maximum 16384 à la fois. J'aimerais savoir d'où vient cette limite
> (imposée par l'OS ou par ocaml ?).


ça ne vient pas d'OCaml car si je regarde le code source de la fonction
Unix.read je constate que c'est juste un wrappeur de la fonction C du même
nom.

Il est possible que pour des raisons de performance l'OS préfère transférer
des bloques de 16 Ko.

> La doc "man 2 read" m'indique que ce n'est pas a priori une erreur,
> mais il me semble qu'en C on peut lire plus que ça en une fois.


comme je l'ai dit la fonction OCaml n'est qu'un wrappeur de la fonction C,
donc celons toute probabilité le comportement sera le même en C.

> J'utilise ocaml 3.11.2 sous Linux Debian 5, 32 bits.
> Pour observer la chose, on peut utiliser :
> open Unix;;
> let check name =
> let n = (stat name).st_size in
> let s = String.make n ' ' in
> let fd = openfile name [O_RDONLY] 0o600 in
> let k = read fd s 0 n in
> close fd;
> k;;


tu devrais utiliser String.create au lieu de String.make, cela permettra
d'économiser l'initialisation ici inutile.

[..]
> done;
> close fd;
> s;;


pour lire un fichier il me semble que cette méthode est plutôt pas mal :

let load_file f =
let ic = open_in f in
let n = in_channel_length ic in
let s = String.create n in
really_input ic s 0 n;
close_in ic;
(s)

tu peux trouver d'autres méthodes valides ici :


A+
Blue Prawn (22/03/2010, 02h05)
>> let readbytes name =

Je crois que si il reste moins d'octets à lire que n dans le fichier, tu
risques fort d'entrer dans une boucle infinie avec ce code, car ofs sera
toujours inférieur à n. Il faut que tu testes aussi si read retourne 0.

A+
toucan (22/03/2010, 14h20)
Blue Prawn wrote:
[..]
> tu peux trouver d'autres méthodes valides ici :
>
> A+


Merci, je vais regarder ça. C'est en tout cas plus propre
que ce que j'ai fait plus haut ;-)
Discussions similaires