Copie de fichier - C++ - Programmation
Marsh Posté le 28-10-2002 à 17:19:33
sur windows :
CopyFile
Marsh Posté le 29-10-2002 à 01:20:35
Code :
|
C'est la méthode rustique.
Normalement, il faudrait tester aussi le succès de fputc et fclose.
Marsh Posté le 29-10-2002 à 13:00:23
Musaran a écrit a écrit :
|
ça va ramer à mort ton truc
il vaut mieux bufferiser
et en cherchant un peu sur le net (google) tu devrais trouver des truc beaucoup + optimisés
Marsh Posté le 29-10-2002 à 13:21:47
[SDF]Poire a écrit a écrit : ça va ramer à mort ton truc il vaut mieux bufferiser et en cherchant un peu sur le net (google) tu devrais trouver des truc beaucoup + optimisés |
ah ben quand il dit que c'est rustique, c'est pas pour rien
Marsh Posté le 29-10-2002 à 13:50:45
chrisbk a écrit a écrit : ah ben quand il dit que c'est rustique, c'est pas pour rien |
Marsh Posté le 29-10-2002 à 15:49:43
pascal_ a écrit a écrit : Les FILE* sont deja bufferisées. |
je demande des preuves...
tu fais une copie caractère par caractère ça copie char par char il va pas te copiter un certain nb de char en mem avant de te les copiter physiquement...
Marsh Posté le 29-10-2002 à 16:38:59
Il vaut utiliser CopyFile que du code perso car:
- il preserve les attributs de date de modif
- il doit verifier si la taille dispo sur le disque est suffisante, et en cas d'echec il ne reste pas de fichier partiel
Marsh Posté le 29-10-2002 à 16:45:03
Y'a pas une commande dans la librairie standard du C pour faire ca?
Si je veux porter mon programme sous Linux apres?
Marsh Posté le 29-10-2002 à 17:23:06
FILE* est bien bufferisé.
Si tu utilises des descripteurs avec les
fonctions open, close, write... ce n'est
pas du bufferise.
C'est la différence entre les deux methodes.
Marsh Posté le 29-10-2002 à 18:57:44
pascal_ a écrit a écrit : FILE* est bien bufferisé. Si tu utilises des descripteurs avec les fonctions open, close, write... ce n'est pas du bufferise. C'est la différence entre les deux methodes. |
Tu crois que je vais te croire sur parôle avec 4 posts en 2 ans ?
Marsh Posté le 29-10-2002 à 20:51:58
[SDF]Poire a écrit a écrit : Tu crois que je vais te croire sur parôle avec 4 posts en 2 ans ? |
mieux vaut préférer quelqu'un qui écrit pas bcp que quelqu'un qui en écrit des tonnes pour ne rien dire.
les fonction Fopen, fread, ... ouvrent de base un stream et utilisent un buffer, preuve en est que dans les fonctions associées il existe une fonction fflush qui a pour but de vider les buffers attachés au stream ouvert. il n'existe pas de fonctions équivalentes avec les open,creat, ...
Marsh Posté le 29-10-2002 à 20:54:07
[SDF]Poire a écrit a écrit : Tu crois que je vais te croire sur parôle avec 4 posts en 2 ans ? |
man fopen
Citation : |
http://campuscgi.princeton.edu/man?fopen
Marsh Posté le 29-10-2002 à 21:58:11
y'en reste pas moins que lire un gros coup avec fread ira plus vite que les 250x avec fgetc
Marsh Posté le 29-10-2002 à 22:16:40
vs avez fumez ou quoi ?
C pas possible ce que vous dite
a la limite il foue le char en mem avant de l'écrire physiquement, donc il fait un buffer de 1 char
Mais il bufferise surement pas un certain nombre de char avant de les écrires pour aller + vite... comment il C quand C fini ds ce cas ? il atta un peu ?
Marsh Posté le 29-10-2002 à 22:19:00
[SDF]Poire a écrit a écrit : Mais il bufferise surement pas un certain nombre de char avant de les écrires pour aller + vite... comment il C quand C fini ds ce cas ? il atta un peu ? |
faudrait faire un poil plus confiance a la doc, et quand y'a un truc qui te semble pas evident, penser a y reflechir avant de dire n'importe quoi...
Marsh Posté le 29-10-2002 à 22:20:02
je connais pas l'implémentation des f*, mais rien n'empeche d'écrire physiquement :
- si n chars en mémoire
- si appel a fclose()
Marsh Posté le 29-10-2002 à 22:21:47
lorill a écrit a écrit : faudrait faire un poil plus confiance a la doc, et quand y'a un truc qui te semble pas evident, penser a y reflechir avant de dire n'importe quoi... |
Comment veux-tu qu'il bufferise une suite d'appel à fgetc et fputc ?
de + fait les test de perf en bufferisant (prend 1024 en taille de buffer ce qui n'est pas ennorme) et tu verra déjà la diff
C méga long la copie octet par octet
Marsh Posté le 29-10-2002 à 22:23:05
lorill a écrit a écrit : je connais pas l'implémentation des f*, mais rien n'empeche d'écrire physiquement : - si n chars en mémoire - si appel a fclose() |
T'as déja crashé la lecture/écriture ds un fichier ? ou oublié un fclose ? et t'as perdu des données ?
moi ça m'es jamais arrivé qu'un truc ne soit pas écris...
Marsh Posté le 29-10-2002 à 22:24:42
[SDF]Poire a écrit a écrit : Comment veux-tu qu'il bufferise une suite d'appel à fgetc et fputc ? |
t'as un buffer associé a la structure FILE, ca me semble évident comme mécanisme...
[SDF]Poire a écrit a écrit : de + fait les test de perf en bufferisant (prend 1024 en taille de buffer ce qui n'est pas ennorme) et tu verra déjà la diff C méga long la copie octet par octet |
normal, tu fais 1024 fois plus d'appel qu'avec le buffer, mais c'est quand même moins long que si y'avait un accès disque a chaque lecture.
Marsh Posté le 29-10-2002 à 22:26:41
[SDF]Poire a écrit a écrit : T'as déja crashé la lecture/écriture ds un fichier ? ou oublié un fclose ? et t'as perdu des données ? moi ça m'es jamais arrivé qu'un truc ne soit pas écris... |
mais il insiste en plus
fais voir un fprintf sans \n sur stdout, puis un gros sleep, et un autre fprintf avec \n pour rire...
Marsh Posté le 29-10-2002 à 22:28:52
[SDF]Poire a écrit a écrit : vs avez fumez ou quoi ? C pas possible ce que vous dite |
Read ahead, tu connais ?
Tu demande un caractère, mais il en lit 2500 (valeur pipeau pour l'explication), car lire 2500 ou 1 caractère, ça a le même cout. Sauf que si après tu lui demandes le suivant, bah, il l'a déjà lu, c'est dans son buffer, donc il y a juste à aller le lire en mémoire, et pas sur le disque, d'ou gain en vitesse, c'est bien(c)
Marsh Posté le 29-10-2002 à 22:32:37
Donc si je fais un putc ds un fichier que je crash le prog (donc aucune libération ni aucun flush ni fclose) il sera pas écrit selon toi ?
Marsh Posté le 29-10-2002 à 22:34:29
[SDF]Poire a écrit a écrit : Donc si je fais un putc ds un fichier que je crash le prog (donc aucune libération ni aucun flush ni fclose) il sera pas écrit selon toi ? |
oui.
Edit : Euh, on parle des fonctions f, donc fputc
Marsh Posté le 29-10-2002 à 22:38:10
kadreg a écrit a écrit : oui. Edit : Euh, on parle des fonctions f, donc fputc |
euh.... C des macros de putc et getc.....
le débat et momentanément clos
Marsh Posté le 29-10-2002 à 22:38:51
source de fputc
http://sources.redhat.com/cgi-bin/ [...] root=glibc
macro _IO_putc_unlocked
http://guma.ii.fmph.uniba.sk/linux [...] .html#:329
tiens donc, mais quelle est donc cette affectation en mémoire ?
Edit: non, le débat n'est pas clos, je cherchais a prouver mes dires, voila qui est fait. Maintenant le débat est clos.
Marsh Posté le 29-10-2002 à 22:39:10
[SDF]Poire a écrit a écrit : je demande des preuves... |
/* Copyright (C) 1991, 1995, 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
/* Close a stream. */
int
fclose (stream)
FILE *stream;
{
int status;
if (!__validfp (stream))
{
__set_errno (EINVAL);
return EOF;
}
if (stream->__mode.__write &&
/* Flush the buffer. */
__flshfp (stream, EOF) == EOF)
return EOF;
/* Free the buffer's storage. */
if (stream->__buffer != NULL && !stream->__userbuf)
free (stream->__buffer);
/* Close the system file descriptor. */
if (stream->__io_funcs.__close != NULL)
status = (*stream->__io_funcs.__close) (stream->__cookie);
else if (!stream->__seen && stream->__cookie != NULL)
status = __stdio_close (stream->__cookie);
else
status = 0;
/* Nuke the stream, making it available for re-use. */
__invalidate (stream);
return status < 0 ? EOF : 0;
}
Marsh Posté le 29-10-2002 à 22:42:00
lorill a écrit a écrit : source de fputc http://sources.redhat.com/cgi-bin/ [...] root=glibc macro _IO_putc_unlocked http://guma.ii.fmph.uniba.sk/linux [...] .html#:329 tiens donc, mais quelle est donc cette affectation en mémoire ? Edit: non, le débat n'est pas clos, je cherchais a prouver mes dires, voila qui est fait. Maintenant le débat est clos. |
G dit momentanément
Marsh Posté le 29-10-2002 à 22:42:46
[SDF]Poire a écrit a écrit : G dit momentanément |
n'empeche que tu peux aller te coucher maintenant
Marsh Posté le 29-10-2002 à 22:43:44
lorill a écrit a écrit : n'empeche que tu peux aller te coucher maintenant |
C ce que G T partit faire
ye a y sont pas en vacances
Marsh Posté le 29-10-2002 à 22:59:12
oki je m'incline
(<mauvaise foi>n'empéche C plus rapide avec un buffer </mauvaise foi> )
Marsh Posté le 30-10-2002 à 17:47:28
Citation : |
C'est normal : FILE* a un bufffer de taille ridicule. Si tu prends un buffer plus grand, les performances vont être bien meilleurs (surtout avec les disques durs actuels).
Voila, tout s'explique.
(C'est seulement mon 5ieme post, mais bon, je réfléchit avec de poster des bétises)
Marsh Posté le 31-10-2002 à 02:51:22
pascal_ a écrit a écrit : Les FILE* sont deja bufferisées. |
Oui (comme cela a été asséné).
Le code incorpore un buffer dans l'application.
Cela est bon pour la performance, car sinon un appel système systématique serait vraiment catastrophique.
Conséquence malheureuse: une écriture réelle peut échouer après le succès d'une écriture logique (penser retrait de disquette).
Une bonne raison de n'ouvrir les fichiers que quand on en a besoin, et de les fermer sitôt fini.
A noter, l'OS lui-même gère un autre tampon.
Les fonctions de fichiers du C sont basiques. Pas de copie standard.
Marsh Posté le 31-10-2002 à 04:42:51
[OT]
moralite:
essayez de guider un aveugle il vous frappera avec
sa cane.
[/OT]
Aussi une autre difference (majeure) de fread et read (ou _read sous windows)
c'est que fread fait partie de la librairie d'IO standard
de la libc, alors que read est une fonction de la librairie systeme propre a chaque OS (<unistd.h> ou <io.h> ).
En clair read fait un appel systeme systematiquement, fread ne fait un appel systeme que si son cache se vide ou se remplit (suivant qu'on consomme ou produit du contenu).
C'est la que ca devient interessant:
le cache de fread n'est pas la pour limiter le nombre d'ecriture ou de lecture directement depuis le disque, puisque comme quelqu'un l'a fait remarquer la valeur par defaut de la taille du cache est ridiculement basse (4Ko) pour un PC actuel! Non en fait le cache de fread permet simplement de limiter les appels systemes qui meme s'ils sont couteux ne coutent pas autant (a eux seuls) que le cout de la lecture/ecriture sur le disque.
Ce qui n'est pas forcement dit c'est que l'appel a l'OS est lui-meme caché avant l'acces au disque.
L'avantage c'est que l'OS est configure pour avoir un cache de taille optimal (fixe par l'OS) vers le disque. Un autre avantage c'est que ce cache comme il ne fait pas partie du programme peut-etre flushe normalement quand le programme termine *anormalement*. C'est a dire que le systeme ferme tous les descripteurs de fichiers associes au programme qui vient de crasher (pas de fichiers qui restent ouverts inutilement) et flushe les buffers associes..
Evidemment rien de tout ceci ne fonctionne lorsque c'est l'OS qui provoque le plantage: c'est pour ca que windows et sa libc proposent un mode "critique" (mode d'ouverture "c" ), qui fait que le "fflush" du C flushe vraiment le contenu du cache systeme. (via l'appel systeme "_commit()" ).
Autre chose, on peut faire appel a la methode read ou _read de l'OS sans devoir linker avec la libc, simplement en faisant un appel systeme. C'est ce que fait implicitement la libc, plus une ou deux autres choses comme verrouiller le fichier, valider le handle etc..
A noter qu'a ces deux buffers, l'un dans la libc, l'autre dans l'OS, s'ajoutent d'autres buffers qui peuvent etre nombreux pour des acces reseaux par exemple ou au contraire tres peu nombreux pour ce qui est des affichages sur l'ecran.
Conclusion: si vous voulez faire du code portable: utilisez fread exclusivement et oubliez tout ce que j'ai dit. Si vous voulez faire du code critique: collez le plus possible a l'OS, parce que la doc ANSI ne vous dira pas tout.
A+
LeGreg
Marsh Posté le 28-10-2002 à 17:06:17
Salut, cela fait a peu près 3 ans que j'ai pas touché a ce langage et maintenant j'en ai besoin
je recherche un script me permettant de copier un fichier ou de le creer à la racine du disque
un fichier du genre (si mes souvenir sont bon)
#include<stdio.h>
#include<conio.h>
int main()
{
copie mon fichier source "truc.nfo" vers c:\\
// voila c tout ce que je veux mais c affreux je m'en rappel plus
}
Merci d'avance