Ecrire un fichier à partir d'un TFileStream (pointant sur un autre fichier)

Signaler
Messages postés
249
Date d'inscription
mardi 5 août 2003
Statut
Membre
Dernière intervention
15 juillet 2006
-
Messages postés
249
Date d'inscription
mardi 5 août 2003
Statut
Membre
Dernière intervention
15 juillet 2006
-
Hello tout le monde.

J'ai un ptit problème : mon programme ouvre un gros fichier de 150Mo (donc je préfère passer par un FileStream qu'un MemoryStream pour travailler dessus).

Seulement j'aimerais faire un menu Enregistrer sous. Donc ça enregistrerait le contenu de mon FileStream dans un autre fichier (et donc le 1er serait inchangé). Je ne trouve vraiment pas comment faire à part passer par un MemoryStream (mais vu la taille de mon fichier vive la mémoire...).

Quelqu'un a-t-il une solution ?
Merci d'avance :)

13 réponses

Messages postés
249
Date d'inscription
mardi 5 août 2003
Statut
Membre
Dernière intervention
15 juillet 2006

Merci pour la remarque mais si, j'ai cherché. Parce que justement je ne veux pas copier un fichier !

Je veux ouvrir un fichier, modifier des octets dedans, et sauvegarder le tout modifier dans un autre fichier. Avec un TMemoryStream c'est simple mais je voulais savoir si c'était possible avec un TFileStream (vu la taille de mon fichier).
Messages postés
249
Date d'inscription
mardi 5 août 2003
Statut
Membre
Dernière intervention
15 juillet 2006

le tout modifié*
désolé

Attention : en changeant, en ajoutant des octets dans un fichier, tu risques de le bousiller (ca dépend de son type).

Pour ta question : MonStream.savetostream('C:\mon_fichier.txt'). //Fonctionne avec un TFileStream. //SaveToStream : en faisant TStream puis la touche F1, tu serais tombé dessus.

Maintenant pour modifier ton fichier : ca dépend précisement de ce que tu veux faire car plusieurs approche sont envisageables.

@+
Messages postés
249
Date d'inscription
mardi 5 août 2003
Statut
Membre
Dernière intervention
15 juillet 2006

Oui justement j'avais lu ce fameux SaveToStream. Hé bien mon Delphi ne le connais pas pour les TFileStream. Je ne sais pas pourquoi.

Sinon ça ne résous pas mon problème : j'ouvre mon fichier avec TFileStream (en lecture seulement). Je voudrais faire des modifs dessus (qui ne seront jamais écrite en dur dans le fichier), puis enregistrer ce contenu modifié dans un autre fichier. Je veux donc que le 1er reste intact (bien qu'on ait fait les modifs sur ce modèle).

Je pense que ce n'est pas possible sans TMemoryStream mais je demandais au cas où ça soit possible avec un TFileStream.

Je n'ai pas testé

Procedure ChangeMyFile(AFile,NewFile : string);
Var
FS1,FS2 TFileStream;
Begin
FS1:=TFileStream.Create(AFile,fmOpenRead);
FS2:=TFileStream.Create(NewFile,fmCreate);
FS1.Position.FS1.Size;
Try
FS1.Write(PChar('Codes-Sources')^,length('Codes-Sources'));
Finally
FS1.Position:=0;
FS2.CopyFrom(FS1,FS1.Size);
Finally
FreeAndNil(FS2);
FreeAndNil(FS1);
End;
End;

Procedure TForm1.Button1OncliCk(Sender : TObject);
var
newFile : string;
Begin
If Savedialog1.execute then NewFile:=savedialog1.filename;
With Opendialog1 do
Begin
Execute;
ChangeMyFile(FileName,NewFile);
End;
End;

Ouvre notepad : regarde à la fin de ton fichier (exe,wav,mp3,avi, zip ...). tu vois "Codes-sources". Ouvre ton fichier : il plante ===> On ne modifie pas un fichier (sauf texte) sans le bousiller.
Messages postés
249
Date d'inscription
mardi 5 août 2003
Statut
Membre
Dernière intervention
15 juillet 2006

J'avais fait un truc du genre. Le problème c'est que .write ne fera rien vu que le fichier est ouvert en lecture et pas écriture. Et si on rajoute l'écriture ça écrit direct dans le fichier (ce que je ne veux pas)... -_-

Je ne pense pas que ça soit possible sans MemoryStream (après tout ils servent à ça...).

Merci d'avoir essayé quand même.

Bien dans ce cas là, on réfléchit deux minutes et on obtient cela :

Procedure ChangeMyFile(AFile,NewFile : string);
Var
FS1,FS2 :TFileStream;
Begin
FS1:=TFileStream.Create(AFile,fmOpenRead);
FS2:=TFileStream.Create(NewFile,fmCreate);
FS1.Position:=0;
Try
FS2.CopyFrom(FS1,FS1.Size);
FS2.Position:=FS2.Size;
FS2.Write(PChar('Codes-Sources')^,length('Codes-Sources'));
Finally
FreeAndNil(FS2);
FreeAndNil(FS1);
End;
End;

procedure TForm1.Button1Click(Sender: TObject);
var
newFile : string;
Begin
If Savedialog1.execute then NewFile:=savedialog1.filename;
With Opendialog1 do
Begin
Execute;
ChangeMyFile(FileName,NewFile);
End;

end;

A mon avis si tu bloques sur ce genre de chose c'est que tu as pas le niveau pour continuer ton projet. Plutot que de jouer à Final Fantasy tu devrais lire quelques tutoriaux

Et ce que je te passes fonctionne : je viens de tester (chose que tu n'as meme pas eu le courage de faire)

J'explique :

On copie FS1 dans FS2. On se place à la fin de FS2 (qui est en écriture) et on rajoute le texte. On libère tout donc on créer le fichier.

Autre solution envisageable : copyFile. On ouvre le fichier en écriture OpenWrite on fait la modif et on enregistre.

J'ai du mal à croire que tu as cherché ou alors ta méthode de recherche est à revoir sérieusement.
Messages postés
249
Date d'inscription
mardi 5 août 2003
Statut
Membre
Dernière intervention
15 juillet 2006

Non parce que là le fichier sera créé tout le temps !

Bon je réexplique : je veux ouvrir un fichier. Son contenu apparait dans ma fenêtre. je peux modifier, faire ce que je veux etc... Et je fais Fichier > Enregistrer sous... pour enregistrer le contenu de ma fenêtre dans le fichier. Je peux aussi ne pas sauvegarder si je veux ! Le fonctionnement est pareil que bloc notes ou autres. Mais à ce moment là le contenu de la fenêtre doit être chargé dans un MemoryStream d'où ma question.

PS : je ne peux pas me permettre non plus de lire le contenu de la fenêtre et de tout réécrire (fichier de 150 Mo).

Donc voilà je pense que la seule solution à ma question est le MemoryStream malheureusement...
Messages postés
249
Date d'inscription
mardi 5 août 2003
Statut
Membre
Dernière intervention
15 juillet 2006

Oublie ce sujet. Je ni tout mon fichier (même s'il fait 150Mo) et je ne le charge ni dans un Memo.

Je sais que je ne peux pas modifier un fichier (surtout typé) comme ça (voir une des autres nombreuses questions pourries que j'ai posté, via une petite recherche). Ce n'est pas le cas mais imagine que je modifie juste quelques octets d'une sauvegarde d'un jeu par exemple. C'est à peu près ça que je fais mais sur un autre fichier plus gros.

Je t'ai passé un exemple de code ou tu rajoutes un simple string dans un fichier :si tu utilises un fichier texte pour faire cela, en double cliquant dessus tout se passe bien. Refais la meme chose avec un mp3. Lance ton WindowsMediaPlayer pour l'ouvrir : tu ne pourras pas. Pourtant je n'ai que ajouté que quelques octets dans le fichier.
Messages postés
249
Date d'inscription
mardi 5 août 2003
Statut
Membre
Dernière intervention
15 juillet 2006

Oui je suis au courant comme je l'ai dit. Je suis pas totalement bête. Je le redis donc encore (bis) : c'est un fichier non typé (dans le sens où il n'est pas lit dans un programme). C'est juste une sorte de fichier ressource. Je n'ai jamais eu AUCUN pb en le modifiant comme je le voulais.

Hors sujet.
Messages postés
249
Date d'inscription
mardi 5 août 2003
Statut
Membre
Dernière intervention
15 juillet 2006

shining merci pour ton idée d'écrire le fichier dans le répertoire temp ! C'est pas bête et ça me plait bien comme idée (fallait juste y penser...).

Merci à toi :)