Discussion:
lecture de fichier dans le module Unix
(trop ancien pour répondre)
toucan
2010-03-20 12:23:59 UTC
Permalink
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
2010-03-22 00:01:51 UTC
Permalink
Post by toucan
Bonjour,
Bonjour,
Post by toucan
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.
Post by toucan
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.
Post by toucan
J'utilise ocaml 3.11.2 sous Linux Debian 5, 32 bits.
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.
Post by toucan
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;;
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 :
http://ocaml.tuxfamily.org/Lire_un_fichier

A+
Blue Prawn
2010-03-22 00:05:52 UTC
Permalink
Post by toucan
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;;
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
2010-03-22 12:20:19 UTC
Permalink
Post by toucan
Post by toucan
Bonjour,
Bonjour,
Post by toucan
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.
Post by toucan
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.
Post by toucan
J'utilise ocaml 3.11.2 sous Linux Debian 5, 32 bits.
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.
Post by toucan
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;;
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)
http://ocaml.tuxfamily.org/Lire_un_fichier
A+
Merci, je vais regarder ça. C'est en tout cas plus propre
que ce que j'ai fait plus haut ;-)

Loading...