Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

fopen

15 réponses
Avatar
mb
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

10 réponses

1 2
Avatar
Olivier Miakinen
Bonjour,

Le 02/07/2011 18:42, mb a écrit :

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 ».

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.

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
Avatar
mb
In article <4e0f512c$,
Olivier Miakinen <om+ wrote:

> 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



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;}

$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

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 )

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é

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
Avatar
Olivier Miakinen
Le 04/07/2011 07:47, mb a écrit :

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;}

$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.

le fseek replace le curseur , mais dans le mode a il refuse de passer eof



Même dans le mode a+ ?

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.

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).
Avatar
mb
In article <4e1155bd$,
Olivier Miakinen <om+ wrote:

> 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

> 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
Avatar
Mickael Wolff
On 07/04/11 23:34, mb wrote:
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. »
Avatar
mb
In article <4e238ba2$0$25245$,
Mickael Wolff wrote:

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);



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
Avatar
Mickael Wolff
On 07/18/11 18:33, mb wrote:
Salut ,
je connais pas Linux



Ce n'est pas un comportement spécifique à Linux. C'est un
comportement défini par POSIX.

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.
Avatar
mb
In article <4e24f283$0$15874$,
Mickael Wolff wrote:

On 07/18/11 18:33, mb wrote:
> Salut ,
> je connais pas Linux

Ce n'est pas un comportement spécifique à Linux. C'est un
comportement défini par POSIX.

> 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
Avatar
Antoine Polatouche
Le 20/07/2011 01:47, mb a écrit :

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);
Avatar
mb
In article <j06q0j$28cj$,
Antoine Polatouche wrote:

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);



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
1 2