Voici une source permettant de fragmenter un fichier en plusieurs autre.
J'ai fais cette source pour le transport sur disquette et également pour pouvoir télécharger un fichier en plusieurs fois.
Pour faire l'acquisition de la taille du fichier j'ai tout simplement utilisé fseek() pour connaitre la position dans le fichier du dernier octet.
N'existe t'il pas une fonction ?
J'ai également un autre petit problème c'est pour convertir un int en chaîne de caractère.
J'utilise la fonction fcvt(), n'existe t'il pas une fonction ainsi pour avoir une meilleure porabilité ?
Un truc, j'ai pas limité la taille du buffer entre le fichier source et le fichier de destination car je n'ai pas de problème de disponibilté de mémoire.
De toute façon je fais des fragments de 10 Mo maximum.
Source / Exemple :
/********************************************************/
/* */
/* FRAGMENTEUR/DEFRAGMENTEUR DE FICHIERS */
/* */
/********************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FRAGMENTER 1
#define MAX 20
/* prototypes */
int acquisition (char *filename, long *fragsize, int *erasefrag);
int filefrag (char *filename, long fragsize);
int fbuild (char *filename, int erasefrag);
long fsize (char *filename);
void fname (char *filename, char *newname, int nb);
/* main() */
int main (void)
{
int choix;
int erase;
long fragsize;
char filename[MAX];
choix = acquisition(filename, &fragsize, &erase);
if(choix == FRAGMENTER)
filefrag(filename, fragsize);
else
fbuild(filename, erase);
/* fin du programmme */
fflush(stdin);
getchar();
return 0;
}
/******** acquisition des données pour le programme *********/
int acquisition (char *filename, long *fragsize, int *erase)
{
int choix;
/* choix = fragment/reconstruire */
do
{
printf("\n\n1=fragmenter, 2=reconstruire : ");
scanf("%d",&choix);
}
while(choix < 1 || choix > 2);
/* acquisition des données nécessaires */
fflush(stdin);
printf("\nNom du fichier : ");
gets(filename);
if(choix == FRAGMENTER)
{
printf("\nEntrez la taille en Ko des fragments (1 Mo = 1024 Ko) : ");
scanf("%ld", fragsize);
- fragsize *= 1024; /* taille en octets */
}
else
do
{
printf("\nVoulez vous effacer les fragments (O/N) ?");
switch( getchar() )
{
case 'o' :
case 'O' : *erase = 1;
break;
case 'n' :
case 'N' : *erase = 0;
break;
default : *erase = -1;
}
}
while(*erase == -1);
return choix;
}
/* -----------------------------------------------------------------------
fonction : int filefrag (char *filename, long fragsize)
description : filefrag() permet de fragmenter un fichier en
plusieurs autre d'une taille prédéfinie.
val envoyées : - filename = nom du fichier à fragmenter.
- fragsize = taille de chaque fragment en octets.
val renvoyées : - si succès : 1
- si erreur : 0
portabilité : dos uniquement.
(à cause de fcvt() dans fname())
exemple : filefrag("test.txt", 1024);
ici on fragmente test.txt en plusieurs fichiers
de 1 Ko (sauf le dernier fragment).
La taille du dernier fragment varie en fonction
du nombre d'octets de donnés qu'il reste à copier.
------------------------------------------------------------------- */
int filefrag (char *filename, long fragsize)
{
FILE *fsource;
FILE *fdest;
char *buffer;
char filefrag[MAX];
fpos_t taille;
fpos_t sizetemp;
int nb = 0;
/* passage à la ligne */
puts("");
/* détection de la taille du fichier source */
taille = fsize(filename);
/* ouverture du fichier à fragmenter */
if( (fsource = fopen(filename,"rb")) == NULL)
{
fprintf(stderr, "Fichier %s inexistant !", filename);
return 0;
}
/* fragmentation du fichier */
buffer = malloc(fragsize);
while(taille > 0)
{
if(taille <= fragsize)
sizetemp = taille;
else
sizetemp = fragsize;
fname(filename ,filefrag, ++nb);
puts(filefrag);
fdest = fopen(filefrag,"wb");
fread(buffer, sizetemp, 1, fsource);
fwrite(buffer, sizetemp, 1, fdest);
fclose(fdest);
taille -= sizetemp;
}
free(buffer);
/* fermeture du fichier source */
fclose(fsource);
/* fin de la fragmentation */
printf("\n%s fragmente en %d fichiers...", filename, nb);
return 1;
}
/* -----------------------------------------------------------------------
fonction : void fname (char *filename, char *newname, int nb)
description : fname() permet de générer un nom de fichier
(newname) identique à filename mais sans extension
et suivi d'un numéro nb
val envoyées : - filename = nom du fichier d'origine.
- newname = nouveau nom de fichier
- nb = numéro à ajouter à la suite du nom
val renvoyées : void
portabilité : dos uniquement.
(à cause de fcvt())
exemple : fname("test.txt", tab, 1);
ici on obtient dans tab[] = "test1".
------------------------------------------------------------------- */
void fname (char *filename, char *newname, int nb)
{
register int k = 0;
char temp[MAX];
/* même nom sans l'extension */
while(filename[k] != '.')
newname[k] = filename[k++];
newname[k] = '\0';
/* on y ajoute le nb à la suite */
itoa(nb, temp, 10);
strcat(newname, temp);
}
/* -----------------------------------------------------------------------
fonction : long fsize (char *filename)
description : fsize permet de déterminer la taille en octets
d'un fichier.
val envoyées : - filename = nom du fichier à analyser.
val renvoyées : - si succès : taille du fichier en octets
- si erreur : -1
portabilité : dos, unix, c ansi, c++ seul
exemple : taille = fsize("test.txt");
ici on stocke dans taille la taille en octets
du fichier test.txt.
------------------------------------------------------------------- */
long fsize (char *filename)
{
FILE *fp;
long taille;
/* ouverture du fichier */
if( (fp = fopen(filename,"rb")) == NULL)
{
fprintf(stderr, "Fichier %s inexistant !", filename);
return -1;
}
/* détection de la taille du fichier */
fseek(fp, 0, SEEK_END);
fgetpos(fp, &taille);
/* fermeture du fichier */
fclose(fp);
return taille;
}
/* -----------------------------------------------------------------------
fonction : int fbuild (char *filename, int erase)
description : fbuild() permet de reconstruire un fichier qui a
été fragmenté à l'aide de filefrag().
val envoyées : - filename = nom du fichier à reconstruire.
- erase = booléen qui détermine si on efface les
fragments après reconxtruction.
val renvoyées : - si succès : 1
- si erreur : 0
portabilité : dos uniquement.
(à cause de fcvt() dans fname())
exemple : fbuild("test.txt", 1);
on reconstruit le fichier test.txt en effaçant
les fragments (test1, test2 ...)
------------------------------------------------------------------- */
int fbuild (char *filename, int erase)
{
FILE *fsource;
FILE *fdest;
char *buffer;
char filefrag[MAX];
long fragsize;
int nb = 1;
/* passage à la ligne */
puts("");
/* ouverture du fichier de destination */
if( (fdest = fopen(filename,"wb")) == NULL)
{
fprintf(stderr, "Erreur de creation du fichier %s !", filename);
return 0;
}
/* détection taille des/du fragment(s) */
fname(filename ,filefrag, nb);
fragsize = fsize(filefrag);
/* allocation de la mem necessaire pour le buffer */
buffer = malloc(fragsize);
/* remplissage du fichier de destination */
while( (fsource = fopen(filefrag,"rb")) != NULL )
{
puts(filefrag);
/* vérif de la taille du fragment */
fclose(fsource);
if(fsize(filefrag) != fragsize)
fragsize = fsize(filefrag);
/* reconstruction fichier */
fsource = fopen(filefrag,"rb");
fread(buffer, fragsize, 1, fsource);
fwrite(buffer, fragsize, 1, fdest);
fclose(fsource);
/* suppression des fragments */
if(erase)
remove(filefrag);
/* préparation pour le prochain fichier */
fname(filename, filefrag, ++nb);
}
free(buffer);
/* fermeture du fichier de destination */
fclose(fdest);
/* fin de la reconstruction */
printf("\nFichier %s reconstruit...", filename);
return 1;
}
Conclusion :
J'ai essayé de faire au plus simple.
Le pricipal bug, c'est quand il faut entrer 1 ou 2 au moment du choix de la fragmentation ou de la reconstruction.
Si l'on entre un caractère, le programme plante.
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.