Discussion:
fopen
(trop ancien pour répondre)
mb
2011-07-02 16:42:08 UTC
Permalink
Bonjour ,

si j'ai créé un fichier contenant 4 octets
xxxx

comment faire pour écrire yyyy à la position 10
en laissant nuls ( ou indéterminés ) les intermédiaires et obtenir
xxxx000000yyyy

j'ai essayé différents modes pour fopen mais il semble
que fseek ne passe jamais le eof
le mode binaire ( b ) n'a pas l'air de faire mieux

merci
--
mb
Olivier Miakinen
2011-07-02 23:27:05 UTC
Permalink
Bonjour,
Post by mb
si j'ai créé un fichier contenant 4 octets
xxxx
comment faire pour écrire yyyy à la position 10
en laissant nuls ( ou indéterminés ) les intermédiaires et obtenir
xxxx000000yyyy
C'est bien « nuls » et pas « indéterminés ».
Post by mb
j'ai essayé différents modes pour fopen mais il semble
que fseek ne passe jamais le eof
Pourtant, la doc PHP de fseek indique le contraire :
http://fr.php.net/manual/fr/function.fseek.php

Curieusement, les pages de manuel des fonctions C sous-jacentes lseek et
fseek ne disent rien.
Post by mb
le mode binaire ( b ) n'a pas l'air de faire mieux
Dans ton cas le mode binaire est recommandé, mais il ne remplace pas
les autres modes : il les complète.

Le mode choisi doit pouvoir autoriser l'écriture (évidemment) mais
certainement aussi la lecture pour pouvoir faire un fseek. Ceci
élimine les modes sans '+' (r, w, a, x et c). Comme tu ne veux pas
supprimer l'ancien contenu du fichier, cela élimine aussi les modes
w+ et x+.

Au final, je te conseille 'r+b' ou 'a+b', ce qui devrait revenir au même
si le fichier existe déjà, puisque tu fais un lseek après. Si tu veux
pouvoir créer le fichier au cas où il n'existerait pas, je te conseille
plutôt 'a+b' car la doc ne précise pas le comportement avec 'r'.

Cordialement,
--
Olivier Miakinen
mb
2011-07-04 05:47:23 UTC
Permalink
Post by Olivier Miakinen
Post by mb
que fseek ne passe jamais le eof
http://fr.php.net/manual/fr/function.fseek.php
c'est bien la doc que je lis

en fait j'avais écrit ( en simplifiant )

<?php

if ($pass==1) // pour créer le fichier et mettre les x
{ $titre="fichedoc/essaidoc";$cont="xxxx";$pos=0;}

if ($pass==2) // pour mettre les y
{ $titre="fichedoc/essaidoc";$cont="yyyy";$pos=10;}

$f=fopen($titre,'w');
fseek($f,$pos,SEEK_SET);
$i=fwrite($f,$cont);

?>

en pensant pouvoir utiliser le même mode pour les 2 passes
mais w efface tout et r+ ne crée pas
le fseek replace le curseur , mais dans le mode a il refuse de passer eof
Post by Olivier Miakinen
Curieusement, les pages de manuel des fonctions C sous-jacentes lseek et
fseek ne disent rien.
en C je n'utilise pas les stdio et autres
mais directement les FSRef et les fct qui vont avec ( systeme Mac )
Post by Olivier Miakinen
Dans ton cas le mode binaire est recommandé, mais il ne remplace pas
les autres modes : il les complète.
ça marche sans le b , mais je n'ai pas besoin de portabilité
Post by Olivier Miakinen
Au final, je te conseille 'r+b' ou 'a+b', ce qui devrait revenir au même
si le fichier existe déjà, puisque tu fais un lseek après. Si tu veux
pouvoir créer le fichier au cas où il n'existerait pas, je te conseille
plutôt 'a+b' car la doc ne précise pas le comportement avec 'r'.
tout compte fait
je fais création avec "w"
et écriture avec r+

merci bien
--
mb
Olivier Miakinen
2011-07-04 06:02:09 UTC
Permalink
Post by mb
en fait j'avais écrit ( en simplifiant )
<?php
if ($pass==1) // pour créer le fichier et mettre les x
{ $titre="fichedoc/essaidoc";$cont="xxxx";$pos=0;}
if ($pass==2) // pour mettre les y
{ $titre="fichedoc/essaidoc";$cont="yyyy";$pos=10;}
$f=fopen($titre,'w');
fseek($f,$pos,SEEK_SET);
$i=fwrite($f,$cont);
?>
en pensant pouvoir utiliser le même mode pour les 2 passes
mais w efface tout et r+ ne crée pas
Oui.
Post by mb
le fseek replace le curseur , mais dans le mode a il refuse de passer eof
Même dans le mode a+ ?
Post by mb
Post by Olivier Miakinen
Dans ton cas le mode binaire est recommandé, mais il ne remplace pas
les autres modes : il les complète.
ça marche sans le b , mais je n'ai pas besoin de portabilité
Ok.
Post by mb
tout compte fait
je fais création avec "w"
et écriture avec r+
Ce n'est pas plus mal, surtout si le fichier peut exister avant et que
tu veux être sûr de le réinitialiser. Note que, pour être tout à fait
propre, je pense que tu ne devrais pas faire le fseek dans la première
passe (ouverture en mode w).
mb
2011-07-04 21:34:11 UTC
Permalink
Post by Olivier Miakinen
Post by mb
le fseek replace le curseur , mais dans le mode a il refuse de passer eof
Même dans le mode a+ ?
je viens d'essayer a et a+
rien à faire , j'ai essayé aussi de mettre le curseur avant eof
mais il le remet systématiquement à eof
le fseek n'a aucun effet
Post by Olivier Miakinen
Post by mb
tout compte fait
je fais création avec "w"
et écriture avec r+
Ce n'est pas plus mal, surtout si le fichier peut exister avant et que
tu veux être sûr de le réinitialiser. Note que, pour être tout à fait
propre, je pense que tu ne devrais pas faire le fseek dans la première
passe (ouverture en mode w).
de tts façon je vais séparer la création vide ( en w )
et faire le reste en r+ ou r

heu , ça manque un peu de logique tout ça ,
pourquoi tous ces modes , ils doivent croire qu'on confond read et write

à +
--
mb
Mickael Wolff
2011-07-18 07:41:45 UTC
Permalink
Post by mb
heu , ça manque un peu de logique tout ça ,
pourquoi tous ces modes , ils doivent croire qu'on confond read et write
Il y a des fichiers qu'on ne peut pas ouvrir en lecture, et d'autres
qu'on ne peut pas ouvrir en écriture. De plus, indiquer au sous-système
POSIX ce qu'on va faire d'un fichier permet à l'implémentation
d'optimiser les accès.

En toute logique, pour trouver sa position dans le fichier, et écrire
dedans, il faut ouvrir le fichier en r+.

Les modes "w" tronquent le fichier à l'ouverture.
Les modes "a" ne permettent que d'ajouter à la fin du fichier des
données (ni au milieu, ni plus loin).

Extrait du manpage fseek sous Linux:
« Opening a file in append mode (a as the first character of
mode) causes all subsequent write operations to this stream to occur at
end-of-file, as if preceded by an
fseek(stream,0,SEEK_END);
call. »
mb
2011-07-18 16:33:43 UTC
Permalink
Post by Mickael Wolff
« Opening a file in append mode (a as the first character of
mode) causes all subsequent write operations to this stream to occur at
end-of-file, as if preceded by an
fseek(stream,0,SEEK_END);
Salut ,
je connais pas Linux
mais comment expliquer que le mode a+ autorise la lecture alors
que le curseur est bloqué à l'eof , le fseek n'agissant pas ?
--
mb
Mickael Wolff
2011-07-19 11:18:43 UTC
Permalink
Post by mb
Salut ,
je connais pas Linux
Ce n'est pas un comportement spécifique à Linux. C'est un
comportement défini par POSIX.
Post by mb
mais comment expliquer que le mode a+ autorise la lecture alors
que le curseur est bloqué à l'eof , le fseek n'agissant pas ?
Euh-- ben c'est ce que l'extrait du man dit : que chaque appel à
fwrite agiera comme si fseek était appelé pour mettre le curseur à la
fin du fichier.
mb
2011-07-19 23:47:23 UTC
Permalink
Post by Mickael Wolff
Post by mb
Salut ,
je connais pas Linux
Ce n'est pas un comportement spécifique à Linux. C'est un
comportement défini par POSIX.
Post by mb
mais comment expliquer que le mode a+ autorise la lecture alors
que le curseur est bloqué à l'eof , le fseek n'agissant pas ?
Euh-- ben c'est ce que [ ... ]
j'aime bien la réaction

mais je pense que
un fcreate , un fopen ( read , write , read-write )
à condition que le mode w ne remette pas le size de la file à 0

associés à fseek ( avec les 3 possibilités ) et ftruncate

auraient suffit

mais il semble que php se soit développé trop vite
et que les défauts corrigés de version en version soient restés
--
mb
Antoine Polatouche
2011-07-20 22:12:43 UTC
Permalink
Post by mb
mais je pense que
un fcreate , un fopen ( read , write , read-write )
à condition que le mode w ne remette pas le size de la file à 0
associés à fseek ( avec les 3 possibilités ) et ftruncate
auraient suffit
mais il semble que php se soit développé trop vite
et que les défauts corrigés de version en version soient restés
depuis php 5.2.6 tu peux utiliser les modes c et c+ ce qui donnerait un
code comme ça:

$fp = fopen($filename,'c+');
$s = fread($fp, 4);
if(strlen($s)<4) fwrite($fp,$motdequatrelettres);
else {
fseek($fp, 10, SEEK_SET);
fwrite($fp,$motenpositiondix);
}
fclose($fp);
mb
2011-07-21 06:43:41 UTC
Permalink
Post by Antoine Polatouche
depuis php 5.2.6 tu peux utiliser les modes c et c+ ce qui donnerait un
$fp = fopen($filename,'c+');
$s = fread($fp, 4);
if(strlen($s)<4) fwrite($fp,$motdequatrelettres);
else {
fseek($fp, 10, SEEK_SET);
fwrite($fp,$motenpositiondix);
}
fclose($fp);
Bonjour ,

je ne cherche plus une solution que j'ai déjà trouvé ,
et xxxx yyyy dans le code que j'ai écrit ( plus haut dans le fil )
étaient juste un exemple

la question était de savoir pourquoi ils ont multiplié les modes
à mon avis inutilement , mais elle n'appelle pas forcément de réponse

merci bien
--
mb
Mickael Wolff
2011-07-24 16:21:08 UTC
Permalink
Post by mb
mais je pense que
un fcreate , un fopen ( read , write , read-write )
à condition que le mode w ne remette pas le size de la file à 0
associés à fseek ( avec les 3 possibilités ) et ftruncate
auraient suffit
Si ça suffit à ton besoin, créé ces fonctions dans un fichier PHP.
Mais pour l'inclusion dans PHP, faudra le faire en C et avoir une bonne
argumentation pour que ce soit accepté.
Post by mb
mais il semble que php se soit développé trop vite
Ça n'a rien à voir avec PHP. Comme je l'ai dit, c'est la faute à
POSIX, et même UNIX (j'ai relu le manpage de la fonction open, et
effectivement, c'est un comportement hérité d'UNIX). D'accord, ces flags
ne sont pas très heureux, ils sont même trompeurs.

Quand à ton idée d'avoir plusieurs fonctions pour ouvrir un fichier,
selon les fonctionnalités qu'on souhaite utiliser, ce n'ést pas
forcément une bonne idée. En l'occurrence, à l'époque où la fonction a
été conçue, il fallait respecter des contraintes importantes liées à la
mémoire et à la puissance des processeurs. Une fonction unique était
plus pertinente.

Mais c'est vrai que PHP pourrait fournir une interface plus simple--
Mais il en faudrait un réel usage, ce qui n'est pas le cas.
mb
2011-07-25 17:36:30 UTC
Permalink
Post by Mickael Wolff
Si ça suffit à ton besoin, créé ces fonctions dans un fichier PHP.
Mais pour l'inclusion dans PHP, faudra le faire en C et avoir une bonne
argumentation pour que ce soit accepté.
le principe de l'inclusion d'un php par du C m'échappe totalement
ceci dit je n'ai pas besoin d'une puissance extraordinaire
( juste amateur )

mais d'accord , je vais écrire des fct php "singeant" le comportement
dont j'ai l'habitude
Post by Mickael Wolff
Post by mb
mais il semble que php se soit développé trop vite
Ça n'a rien à voir avec PHP. Comme je l'ai dit, c'est la faute à
POSIX, et même UNIX (j'ai relu le manpage de la fonction open, et
effectivement, c'est un comportement hérité d'UNIX). D'accord, ces flags
ne sont pas très heureux, ils sont même trompeurs.
je ne connais pas très bien ce qu'il se passe dans les systèmes
mais sur ma machine les modes read write me paraissent plus clairs
les goûts et les couleurs ....
Post by Mickael Wolff
Quand à ton idée d'avoir plusieurs fonctions pour ouvrir un fichier,
selon les fonctionnalités qu'on souhaite utiliser, ce n'ést pas
forcément une bonne idée. En l'occurrence, à l'époque où la fonction a
été conçue, il fallait respecter des contraintes importantes liées à la
mémoire et à la puissance des processeurs. Une fonction unique était
plus pertinente.
Mais c'est vrai que PHP pourrait fournir une interface plus simple--
Mais il en faudrait un réel usage, ce qui n'est pas le cas.
je dois en conclure que read write dans un fichier est peu utilisé ?

pourtant si un fichier contient des données de taille fixe
par exemple des UInt32 ( désolé le type php ne me reviens pas )
les lire et les écrire directement me semble plus efficace qu'une base
de donnée , mais il faudrait mesurer

bonne journée
--
mb
Mickael Wolff
2011-07-26 06:34:09 UTC
Permalink
Post by mb
Post by Mickael Wolff
Si ça suffit à ton besoin, créé ces fonctions dans un fichier PHP.
Mais pour l'inclusion dans PHP, faudra le faire en C et avoir une bonne
argumentation pour que ce soit accepté.
le principe de l'inclusion d'un php par du C m'échappe totalement
ceci dit je n'ai pas besoin d'une puissance extraordinaire
( juste amateur )
Non, tu m'as mal compris. PHP est écrit en C. Les extensions sont
écrites en C. Donc pour que PHP propose par défaut les fonctions que tu
penses meilleures, il faut créer un module PHP en C.
Post by mb
je ne connais pas très bien ce qu'il se passe dans les systèmes
mais sur ma machine les modes read write me paraissent plus clairs
les goûts et les couleurs ....
Sauf que ce ne sont pas des fonctions standards. Or PHP est portable
et c'est construit autour de standards.
Post by mb
je dois en conclure que read write dans un fichier est peu utilisé ?
Ouvrir un fichier en PHP en mode binaire n'est pas courant.
Post by mb
pourtant si un fichier contient des données de taille fixe
par exemple des UInt32 ( désolé le type php ne me reviens pas )
les lire et les écrire directement me semble plus efficace qu'une base
de donnée , mais il faudrait mesurer
Comme tu le dis, il faudrait mesurer. Mais accéder directement à un
fichier depuis PHP a plusieurs gros inconvenient :
- accès concurrent (race conditions)
- impossibilité de répartir les charges avec plusieurs front ends
efficacement
- impossibilité de déporter les IO daccès aux données sur un autre
serveur

Bref, la micro-optimisation d'accéder directement à un fichier pour
changer un nombre a des effets de bords importants.
mb
2011-07-26 13:05:29 UTC
Permalink
Post by Mickael Wolff
Non, tu m'as mal compris. PHP est écrit en C. Les extensions sont
écrites en C. Donc pour que PHP propose par défaut les fonctions que tu
penses meilleures, il faut créer un module PHP en C.
je ne les pense pas meilleures , j'ai juste parlé d'habitude
je ne savais pas qu'on pouvait écrire en C des fonctions "personnelles"
mais la compilation devrait se faire sur le serveur , pour compatibilité
je me trompe ?
je doute que mon fai accepte un truc pareil ! et de toutes façons j'en
suis incapable
Post by Mickael Wolff
Post by mb
je ne connais pas très bien ce qu'il se passe dans les systèmes
mais sur ma machine les modes read write me paraissent plus clairs
les goûts et les couleurs ....
Sauf que ce ne sont pas des fonctions standards.
problèmes de portabilité ?
Post by Mickael Wolff
Comme tu le dis, il faudrait mesurer. Mais accéder directement à un
- accès concurrent (race conditions)
accès au fichier par plusieurs connexions ?
peut-être dis-je une bêtise mais la fonction open ne bloque-t-elle pas
l'accès au autres qui attendent le close ?
Post by Mickael Wolff
- impossibilité de répartir les charges avec plusieurs front ends
efficacement
- impossibilité de déporter les IO daccès aux données sur un autre
serveur
ceci est dépasse ma compréhension
Post by Mickael Wolff
Bref, la micro-optimisation d'accéder directement à un fichier pour
changer un nombre a des effets de bords importants.
effet de bord ? c'est en relation avec les accès multiples ?

bonne journée
--
mb
Mickael Wolff
2011-07-28 08:01:18 UTC
Permalink
Post by mb
je ne les pense pas meilleures , j'ai juste parlé d'habitude
je ne savais pas qu'on pouvait écrire en C des fonctions "personnelles"
PHP est un logiciel libre, tu peux le modifier comme tu veux.
D'ailleurs, c'est très intéressant à lire comme logiciel.
Post by mb
mais la compilation devrait se faire sur le serveur , pour compatibilité
je me trompe ?
Pas la compilation, mais le module devra être déployé sur le serveur,
évidemment.
Post by mb
Post by Mickael Wolff
- accès concurrent (race conditions)
accès au fichier par plusieurs connexions ?
peut-être dis-je une bêtise mais la fonction open ne bloque-t-elle pas
l'accès au autres qui attendent le close ?
Ah non. fopen ouvre un fichier, point. Il est impossible d'empêcher
un processus concurrent de lire ou écrire un fichier. Tu peux poser un
lock sur le fichier avec flock, mais ça suppose que les autres processus
respectent la convention que tu adopte.
Post by mb
Post by Mickael Wolff
- impossibilité de déporter les IO daccès aux données sur un autre
serveur
ceci est dépasse ma compréhension
C'est un problème de répartition des charges. Sur un serveur Web, la
ressource critique et rare sont généralement les entrée-sorties sur le
système de fichiers. Ils sont intrinsèquement lents, soumis à des
limitations matérielles importante. C'est un gros problème qui est
souvent la cause d'effondrement des serveurs.
Post by mb
effet de bord ? c'est en relation avec les accès multiples ?
Oui, c'est une des raisons. L'ensemble de tes accès risquent de
bloquer le traitement des requêtes. Mais surtout, rien ne te garanti que
ce que tu lis et écrit dans le fichier y sera ou y est toujours.
Continuer la lecture sur narkive:
Loading...