J’ai un soucis et j’ai beau chercher, je ne vois pas d’où vient le problème.
Je cherche à récupérer les 128 derniers octets d’un fichier. Pour cela je me place sur le 128ème octet de mon fichier en partant par la fin avec la méthode Seek, mais au final je ne récupère qu’un buffer vide (de dimension 0).
Voilà mon code :
FileStream fs= new FileStream(Path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite );
BinaryReader br = new BinaryReader(fs);
fs.Seek(128, SeekOrigin.End);
byte[] buf1 = new byte[128];
buf1 = br.ReadBytes(buf1.Length);
Je n’ai peut être pas bien saisi le fonctionnement de cette fonction.
Non relevant ici, cher ami.
En C/C++, ou la valeur de retour indique l’éventuelle erreur, il est vrai qu’il est indiqué de verifier. En C# on à nos amies les exceptions.
[quote=“Tzim, post:5, topic: 31652”]Non relevant ici, cher ami.
En C/C++, ou la valeur de retour indique l’éventuelle erreur, il est vrai qu’il est indiqué de verifier. En C# on à nos amies les exceptions.[/quote]
Ceci dit, ca m’a surpris de constater que le Seek dépasse allégrement la fin du fichier et lit quand meme sans lever d’exception.
Donc a priori, pas d’exception si ton fichier est ouvert en RW.
Le ReadBytes doit renvoyer un byte de longueur nulle.
A noter qu’il y’a confusion dans l’utilisation de Readbytes : ReadBytes renvoit un nouveau tableau, il n’est pas nécessaire de lui allouer un buffer au préalable. Pour lire dans un buffer, il faut utiliser Read(byte, int, int).
Le code adéquoit :
using (FileStream fs= new FileStream(Path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite )) {
using (BinaryReader br = new BinaryReader(fs)) {
fs.Seek(-128, SeekOrigin.End);
byte[] buf1 = br.ReadBytes(128);
} }
Il me semble. (Question suivante: quel est l’interet du GC qui est censé disposer les objets quand on s’en sert plus ? (ou plutot quand la ram est pleine))
Faut pas confondre.
Le GC libère les ressources managées. Il passe par là et termine l’existance des objets managés qui n’ont plus lieu d’être.
La méthode Dispose à une autre utilité : elle libère les ressources (natives ou non) planquées derrière l’objet en question. Ici, pour le FileStream, c’est un Handle natif sur le fichier ouvert : Dispose permet de fermer le fichier et de libérer le Handle sans attendre que le GC passe par là (gardant un fichier bloqué par le programme), ce qui n’est pas contrôlable. Dispose ne va pas terminer pour autant la vie de l’objet FileStream.
Faut pas confondre.
Le GC libère les ressources managées. Il passe par là et termine l’existance des objets managés qui n’ont plus lieu d’être.
La méthode Dispose à une autre utilité : elle libère les ressources (natives ou non) planquées derrière l’objet en question. Ici, pour le FileStream, c’est un Handle natif sur le fichier ouvert : Dispose permet de fermer le fichier et de libérer le Handle sans attendre que le GC passe par là (gardant un fichier bloqué par le programme), ce qui n’est pas contrôlable. Dispose ne va pas terminer pour autant la vie de l’objet FileStream.[/quote]
Mais euh… Si tu ferme bien ce genre de choses à la main ? J’veux dire, si pour chaque .Open() que t’a (que ca soit un FileStream, Un SqlDataReader, ou n’importe quoi qui garde qque chose d’ouvert qque part), tu fait bien un .Close(), est-ce que ca vaux quand meme le coup de faire un .Dispose() ?
[quote=“Tzim, post:5, topic: 31652”]Non relevant ici, cher ami.
En C/C++, ou la valeur de retour indique l’éventuelle erreur, il est vrai qu’il est indiqué de verifier. En C# on à nos amies les exceptions.[/quote]
c’est pas tout a fait ce que je voulais dire, en regardant la valeur de retour au debug, il aurait pu voir qu elle etait de plus en plus grande, et le mettre sur la piste du seek dans le mauvais sens.
exception ou pas, si une fonction prend la peine de renvoyer une valeur, c est pas juste pour faire joli.
C’est pas une raison. Si l’objet est IDisposable, il doit etre disposé explicitement, c’est tout B)
Il se peut que le systeme soit assez malin pour essayer de sauver les meubles en nettoyant dans le finalizer (catastrophique niveau perfs) ou qu’il laisse carrement fuir des ressources natives (le finalizer tourne dans un autre thread, parfois c’est impossible de nottoyer correctement de puis un autre thread), il se peut meme que tu ais fais le menage par d’autre methodes, mais faut appeller .Dispose().
Haaaan ok. Faudrait que ca soit écrit comme ca sur MSDN en fait, pour être plus clair, parce que moi je voyais ca comme un « bonus » que tu peut appeler si a un moment t’a besoin d’être sur et certain qu’il est bien disposé. Tiens d’ailleurs question, est-ce que le Code Analyser repere ce genre de trucs ? ou y a un moyen simple (plutot que de passer ses nuits sur MSDN) pour trouver qui est Disposable ? (a part l’intellisense). Par exemple, j’avais jamais pensé que Pen puisse en être un.