#1 Le 06/08/2008, à 17:27
- Jean-Julien
[Résolu] Langage C. Demande d'aide pour Large File support.
Bonjour !
J'ai besoin d'aide.
Je travaille actuellement avec un logiciel de protection d'archive que j'ai codé en Python.
Tout tourne Ok, mais les temps de calcul sont très longs.
Cette application nécessite un langage de plus bas niveau et je dois donc l'écrire en C.
Le programme çi-dessous effectue simplement une copie d'un fichier binaire, mais il est limité à 2 giga octets.
Je dois donc "activer" le Large File Support.
J'avais déjà posté une fois de manière plus générale sur ce sujet il y a quelques mois et un membre m'avait
indiqué ce lien.
http://uw714doc.sco.com/en/man/html.2/Intro.2.html#LargeFileSupport
Je vois là le visage de la solution à mon problème, mais je ne suis pas assez compétant pour m'en sortir.
Ma demande est donc la suivante : En partant du code-source çi-dessous, quelqu'un pourrait-il m'écrire ce qu'il lui manque pour qu'il copie des fichiers supérieurs à 2 go ?
A partir de là, je pourrais recommencer à travailler.
...à moins que je ne sois naïf et la la mise en ouvre du LFS soit plus complexe que je ne l'imagine ??
Merçi d'avance !
===========================================================================
#include <stdio.h>
int main() {
FILE *source, *target;
char in[80], out[80], buffer[1024];
int readed, writed;
printf("in : "); // entrée nom fichier source.
scanf("%s", &in);
printf("out : "); // entrée nom fichier cible.
scanf("%s", &out);
source = fopen(in, "rb"); // ouverture fichier binaire en lecture.
target = fopen(out, "wb"); // ouverture fichier binaire en écriture.
while ((readed = fread(buffer, 1, 1024, source)) > 0) // copie du fichier.
fwrite(buffer, 1, readed, target);
fclose(target); // fermeture des fichiers.
fclose(source);
return(0);
}
============================================================================
Dernière modification par Jean-Julien (Le 06/08/2008, à 20:01)
Hors ligne
#2 Le 06/08/2008, à 18:39
- nicolas.sitbon
Re : [Résolu] Langage C. Demande d'aide pour Large File support.
main.c :
#include <stdio.h>
#include <stdlib.h>
#define IN "path_to_source_file"
#define OUT "path_to_target_file"
int main (void)
{
FILE *source = fopen (IN, "rb"); // ouverture fichier binaire en lecture.
if (source != NULL)
{
FILE *target = fopen(OUT, "wb"); // ouverture fichier binaire en écriture.
if (target != NULL)
{
size_t readed;
char buffer[BUFSIZ];
while ((readed = fread(buffer, (size_t)1, sizeof buffer, source)) > 0) // copie du fichier.
fwrite(buffer, (size_t)1, readed, target);
fclose(target), target = NULL; // fermeture des fichiers.
}
else
{
perror ("fopen " OUT);
}
fclose(source), source = NULL;
}
else
{
perror ("fopen " IN);
}
return 0;
}
compiler ainsi : gcc -D_FILE_OFFSET_BITS=64 main.c -o main
fonctione sous linux et solaris (sparc). Je n'ai pas testé sur d'autres systèmes comme BSD ou HPUX.
Dernière modification par nicolas.sitbon (Le 06/08/2008, à 18:59)
Hors ligne
#3 Le 06/08/2008, à 18:56
- aleph
Re : [Résolu] Langage C. Demande d'aide pour Large File support.
> Jean-Julien
Je ne connais pas ton projet et il est évident que Python est moins rapide que le C, je pense néanmoins que tu fais fausse route.
Si le temps d'interprétation est plus lent sous Python, il n'en demeure pas moins que les tâches à effectuer, du moins certaines, sont assez rapides et quasiment équivalentes à du C, je pense par exemple à tout ce qui touche lau "io".
"Porter" une fonction de copie comme celle proposée n'a pas beaucoup de sens tout simplement parce que l'implémentation sous Python est en C.
Pour donner une idée, un "pickling" d'un objet de 4 Go ne pose pas de problème, je ne l'ai pas expérimenté moi-même, mais je me souviens, il n'y a pas si longtemps, quelques semaines, (forum des développeurs de Python) d'une discussion dans le développement de 2.6 et 3.0 où le pickling d'objets dont les tailles étaient > 4 Go posait quelques problèmes, c'est tout dire.
D'autre part, si c'est pour faire de la copie de fichiers, les appels systèmes sont là pour ça et les modules idoines offert par Python sont très proches de ce que fait le système, shutil, os.stat, ...
Si il y a quelque chose à optimiser, je pense que ce sera plus au niveau Python que tu peux intervenir, "list comprehension, séquence, itérateurs..."
Par ex, es-tu conscient qu'un
f.writelines(sequence)
après un f = open(...) naturellement
peut être dix fois plus rapide qu'une succession de
f.write(ligne) ?
#4 Le 06/08/2008, à 20:00
- Jean-Julien
Re : [Résolu] Langage C. Demande d'aide pour Large File support.
@ nicolas-sitbon
C'est ok ! C'est la réponse dont j'avais besoin pour continuer.
Encore merçi.
Jean-Julien Clérin
Dernière modification par Jean-Julien (Le 06/08/2008, à 20:03)
Hors ligne
#5 Le 06/08/2008, à 20:03
- nicolas.sitbon
Re : [Résolu] Langage C. Demande d'aide pour Large File support.
@ nicolas-sitbon
C'est ok, j'ai c'est la réponse dont j'avais besoin pour continuer.
Encore merçi.
Jean-Julien Clérin
You're welcome!
Hors ligne
#6 Le 06/08/2008, à 21:10
- aleph
Re : [Résolu] Langage C. Demande d'aide pour Large File support.
> Jean-Julien
J'ai jeté un coup d'oeil à ce que tu as donné. Le code est très clair et
lisible (le bon côté de Python et un bon travail de l'auteur), néanmoins j'ai
de la peine à comprendre ce que l'application est censé convertir, une étude
plus approfondie serait nécessaire, surtout dans la compréhension de ce qu'il
faut convertir, la "structure" des fichiers.
Il est évident qu'un code plus propre ne va pas magiquement diviser le temps
d'exécution par dix.
Si il est assez facile de corriger des erreurs, proposer une autre stratégie est
plus délicat. Quelques points en vrac:
- J'ai l'impression générale que si tu codes bien en Python, tu n'utilises pas
toutes les ficelles que Python permet.
- Remplacer
if (vic > 255):
vic = vic - 256
par
vic -= 256 if vic > 255 else vic
- ou remplacer
loopvalue = 0
while loopvalue < len(creuset1):
creuset1[loopvalue]= creuset2[loopvalue]
loopvalue += 1
par
creuset1 = creuset2[:]
- les "list comprehensions" pourrait être plus utilisées
creuset1 = [e for e in creuset2]
- ce qui nous amène gentiment au module array. NumPy ne serait-il pas plus optimal ?
Une liste ne ferait-elle pas l'affaire ?
- Lire le fichier à convertir par morceaux et travailler plus en mémoire.
- La différence entre deux temps/date -> timedelta (class datetime)
- Remplacer
code.append(114)
code.append(92)
code.append(34)
par
code.extend([114, 92, 34]) si code est une liste (ou un objet de NumPy)
Je n'est pas de panacée à proposer, mais il me semble qu'il y ait de la place
pour de l'optimisation. Il n'en demeure pas moins qu'un fichier de 2 Go restera
toujours un fichier de 2 Go.
Amicalement et paresseusement sans les balises de code.
PS de dernière minute
Google - python copy large file renvoie quand même quelques entrées.
#7 Le 06/08/2008, à 21:26
- Jean-Julien
Re : [Résolu] Langage C. Demande d'aide pour Large File support.
@ aleph
Je ne pratique le Python que depuis peu de temps.
Je trouve ce langage très agréable.
En fait, je suis programmeur amateur et autodidacte et mon expérience principale est en Turbo Pascal.
Le vais analyser et étudier tes remarques, elles contiennent des subtilités du Python que je vais expérimenter.
A coup sûr, il va y avoir optimisation du code.
Encore merçi pour ton attention.
Dernière modification par Jean-Julien (Le 06/08/2008, à 23:53)
Hors ligne