begin process at 2012 02 08 09:23:39
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

API

 > TRONQUER UN FICHIER(C - WINDOWS)

TRONQUER UN FICHIER(C - WINDOWS)


 Information sur la source

Note :
Aucune note
Catégorie :API Classé sous :tronquer, fichier, windows, win32, mapping Niveau :Débutant Date de création :03/04/2005 Date de mise à jour :18/05/2007 01:44:37 Vu :8 999

Auteur : NitRic

Ecrire un message privé
Site perso
Commentaire sur cette source (2)
Ajouter un commentaire et/ou une note

 Description

Suite à un problème/demande via le forum: http://www.cppfrance.com/forum.v2.aspx?rm=1&ID=422 230

Permet de tronquer un fichier
    - modifier sa taille
    - retirer X octet(s) dans le fichier(à un endroit quelconque)

cet exemple utilise l'API Windows(directement).

CreateFile(), CreateFileMapping(), MapViewOfFile(), UnmapViewOfFile(),
FlushViewOfFile(), SetFilePointer(), SetEndOfFile(), GetFileSize(),
CloseHandle() et GetLastError().

Il y à aussi une gestion des exceptions en C avec __try/__except pour
les compilateurs les supportants.

Les trois fonctions utilise des entiers 64bits(LONGLONG) pour les fichiers
de plus de 4go, donc, il supporte les fichiers de toutes les tailles.

Le code est un peu `brouillon` mais il fonction et ce n'est qu'un exemple :)

Il n'y à pas de zip car il n'y à qu'un seul et unique petit fichier alors voilà ...

Source

  • #define WIN32_LEAN_AND_MEAN
  • #include <windows.h>
  • #include <stdlib.h>
  • #include <string.h>
  • #include <limits.h>
  • #include <stdio.h>
  • #include <assert.h>
  • #define MEGA_BIT (1024 * 1024) /* 1mb */
  • /* 64bits */
  • void MyCopyMemory( void * dst, const void * src, LONGLONG count )
  • {
  • register BYTE * d = (BYTE *) dst;
  • register BYTE * s = (BYTE *) src;
  • while ( count-- > 0 )
  • *d++ = *s++;
  • }
  • /* modifie la taille d'un fichier */
  • DWORD SetFileSize( void * pHandle, LONGLONG iSize )
  • {
  • /* ici on utilise un LARGE_INTEGER pour les fichiers de plus de 4go(plutôt rare mais bon) */
  • LARGE_INTEGER li;
  • DWORD error = NO_ERROR;
  • assert(pHandle != INVALID_HANDLE_VALUE);
  • assert(pHandle != NULL);
  • li.QuadPart = iSize;
  • /* modifie la position du curseur dans le fichier */
  • li.LowPart = SetFilePointer( pHandle, li.LowPart, &(li.HighPart), FILE_BEGIN );
  • if ( (li.LowPart != 0xffffffff) || (NO_ERROR == (error = GetLastError())) )
  • {
  • /* marque la fin du fichier la ou ce trouve le curseur */
  • if ( !SetEndOfFile( pHandle ) )
  • error = GetLastError();
  • }
  • return error;
  • }
  • /* retire X octet(s) dans un fichier */
  • DWORD RemoveData( void * pHandle, LONGLONG offset, LONGLONG count )
  • {
  • /* même chose ici avec le LARGE_INTEGER */
  • void * map;
  • void * ptr;
  • LARGE_INTEGER fs;
  • DWORD error = NO_ERROR;
  • assert(pHandle != INVALID_HANDLE_VALUE);
  • assert(pHandle != NULL);
  • /* récupère la taille du fichier */
  • fs.LowPart = GetFileSize( pHandle, &(fs.HighPart) );
  • if ( (fs.LowPart == 0xffffffff) && (NO_ERROR != (error = GetLastError())) )
  • return error;
  • /* si `offset` est plus grand que la taille du fichier, on quitte */
  • if ( offset > fs.QuadPart )
  • return ERROR_INVALID_PARAMETER;
  • /* ajuste le nombre d'octet à retirer(si besoin) */
  • if ( (offset + count) > fs.QuadPart )
  • count = (fs.QuadPart - offset);
  • /* création de la map */
  • map = CreateFileMapping(
  • pHandle,
  • NULL,
  • PAGE_READWRITE, /* accès en écriture obligatoire */
  • 0UL, /* on map tout alors 0 partout */
  • 0UL,
  • NULL
  • );
  • if ( NULL == map )
  • return GetLastError();
  • /* opération final */
  • ptr = MapViewOfFile(
  • map,
  • FILE_MAP_READ|FILE_MAP_WRITE, /* accès en écriture obligatoire */
  • 0UL, /* on map tout alors 0 partout */
  • 0UL,
  • 0UL
  • );
  • /******************************************************
  • *
  • `ptr` va contenir l'adresse de la map,
  • qui elle, ce trouve dans `l'address space`
  • du process.
  • Pour manipuler `ptr`, vaut mieux utiliser
  • une autre pointeur.
  • void * newptr = ptr;
  • *(BYTE *)newptr++ = 'y';
  • *(BYTE *)newptr++ = 'z';
  • etc ...
  • Si `ptr` est modifié(le pointeur et non
  • son contenue) alors il sera impossible de
  • libérer/fermer la map ...
  • C'est un peu comme une simple allocation
  • mémoire avec malloc()/free()
  • char * ptr = malloc( 50 * sizeof(char) );
  • ++ptr;
  • free( ptr ); // BOOM!!!
  • *
  • ******************************************************/
  • if ( NULL != ptr )
  • {
  • /* prévenir les `access violation` et compagnie */
  • __try
  • {
  • /* déplace les octets(cast/transtypage obligatoire) */
  • MyCopyMemory( (BYTE *)ptr + offset, (BYTE *)ptr + (offset + count), count );
  • }
  • __except ( EXCEPTION_EXECUTE_HANDLER )
  • {
  • /* Oups! Houston, nous avons un problème ici ... */
  • error = GetExceptionCode();
  • }
  • /*****************************************************
  • *
  • UnmapViewOfFile() flush les données lorsqu'elle
  • est appelé mais, d'après MSDN, il le fait
  • lentement/lâchement alors, un FlushViewOfFile()
  • à sa place ici, un peu plus rapide.
  • *
  • *****************************************************/
  • FlushViewOfFile( ptr, 0UL ); /* 0 car on flush tout */
  • UnmapViewOfFile( ptr ); /* décharge la map */
  • }
  • else
  • {
  • error = GetLastError();
  • }
  • /* ferme la map */
  • CloseHandle( map );
  • if ( NO_ERROR == error )
  • {
  • /* modifie la taille du fichier si aucune erreur */
  • /* taille du fichier moin les octets retirés */
  • return SetFileSize( pHandle, (fs.QuadPart - count) );
  • }
  • return error;
  • }
  • int main( int argc, char * argv[] )
  • {
  • void * hFile; /* handle du fichier */
  • char fname[] = ".\\testfile.txt"; /* nom du fichier à ouvrir/modifier */
  • /* ouverture/création du fichier */
  • hFile = CreateFile(
  • fname,
  • GENERIC_READ|GENERIC_WRITE, /* accès en écriture obligatoire */
  • 0UL, /* aucun partage */
  • NULL, /* aucun attribue de sécurité */
  • /*OPEN_EXISTING*/CREATE_ALWAYS, /* cré/remplace le fichier */
  • FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS, /* attribus/flags */
  • NULL /* pas de template */
  • );
  • /* erreur? */
  • if ( hFile == INVALID_HANDLE_VALUE )
  • {
  • printf("CreateFile(): %lu\n", GetLastError());
  • return 0;
  • }
  • /* modifie la taille du fichier */
  • printf("SetFileSize(): %lu\n", SetFileSize( hFile, MEGA_BIT ));
  • /* retire les octets de 0+1tier jusqu'a 0+2tier */
  • /* on retire 1tier du fichier(le centre/millieu du fichier) */
  • printf("RemoveData(): %lu\n", RemoveData( hFile, (MEGA_BIT / 3), (MEGA_BIT / 3) ));
  • /* ferme le fichier */
  • CloseHandle( hFile );
  • putc( '\n', stdout );
  • return 0;
  • }
#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <stdio.h>
#include <assert.h>

#define MEGA_BIT	(1024 * 1024)	/* 1mb */

/* 64bits */
void MyCopyMemory( void * dst, const void * src, LONGLONG count )
{
	register BYTE * d = (BYTE *) dst;
	register BYTE * s = (BYTE *) src;

	while ( count-- > 0 )
		*d++ = *s++;
}

/* modifie la taille d'un fichier */
DWORD SetFileSize( void * pHandle, LONGLONG iSize )
{

	/* ici on utilise un LARGE_INTEGER pour les fichiers de plus de 4go(plutôt rare mais bon) */
	LARGE_INTEGER li;
	DWORD error = NO_ERROR;

	assert(pHandle != INVALID_HANDLE_VALUE);
	assert(pHandle != NULL);

	li.QuadPart = iSize;

	/* modifie la position du curseur dans le fichier */
	li.LowPart = SetFilePointer( pHandle, li.LowPart, &(li.HighPart), FILE_BEGIN );

	if ( (li.LowPart != 0xffffffff) || (NO_ERROR == (error = GetLastError())) )
	{
		/* marque la fin du fichier la ou ce trouve le curseur */
		if ( !SetEndOfFile( pHandle ) )
			error = GetLastError();
	}

	return error;

}

/* retire X octet(s) dans un fichier */
DWORD RemoveData( void * pHandle, LONGLONG offset, LONGLONG count )
{

	/* même chose ici avec le LARGE_INTEGER */
	void * map;
	void * ptr;
	LARGE_INTEGER fs;
	DWORD error = NO_ERROR;

	assert(pHandle != INVALID_HANDLE_VALUE);
	assert(pHandle != NULL);

	/* récupère la taille du fichier */
	fs.LowPart = GetFileSize( pHandle, &(fs.HighPart) );

	if ( (fs.LowPart == 0xffffffff) && (NO_ERROR != (error = GetLastError())) )
		return error;

	/* si `offset` est plus grand que la taille du fichier, on quitte */
	if ( offset > fs.QuadPart )
		return ERROR_INVALID_PARAMETER;

	/* ajuste le nombre d'octet à retirer(si besoin) */
	if ( (offset + count) > fs.QuadPart )
		count = (fs.QuadPart - offset);

	/* création de la map */
	map = CreateFileMapping( 
							pHandle, 
							NULL, 
							PAGE_READWRITE, /* accès en écriture obligatoire */
							0UL, /* on map tout alors 0 partout */
							0UL, 
							NULL 
							);

	if ( NULL == map )
		return GetLastError();

	/* opération final */
	ptr = MapViewOfFile( 
						map, 
						FILE_MAP_READ|FILE_MAP_WRITE, /* accès en écriture obligatoire */
						0UL, /* on map tout alors 0 partout */
						0UL, 
						0UL 
						);

	/******************************************************
	 *
		`ptr` va contenir l'adresse de la map,
		qui elle, ce trouve dans `l'address space`
		du process.

		Pour manipuler `ptr`, vaut mieux utiliser
		une autre pointeur.

		void * newptr = ptr;

			*(BYTE *)newptr++ = 'y';
			*(BYTE *)newptr++ = 'z';
			etc ...

		Si `ptr` est modifié(le pointeur et non
		son contenue) alors il sera impossible de
		libérer/fermer la map ...

		C'est un peu comme une simple allocation
		mémoire avec malloc()/free()

		char * ptr = malloc( 50 * sizeof(char) );
		++ptr;
		free( ptr ); // BOOM!!!
	 *
	 ******************************************************/
	if ( NULL != ptr )
	{
		/* prévenir les `access violation` et compagnie */
		__try
		{
			/* déplace les octets(cast/transtypage obligatoire) */
			MyCopyMemory( (BYTE *)ptr + offset, (BYTE *)ptr + (offset + count), count );
		}
		__except ( EXCEPTION_EXECUTE_HANDLER )
		{
			/* Oups! Houston, nous avons un problème ici ... */
			error = GetExceptionCode();
		}
		/*****************************************************
		 *
			UnmapViewOfFile() flush les données lorsqu'elle
			est appelé mais, d'après MSDN, il le fait
			lentement/lâchement alors, un FlushViewOfFile()
			à sa place ici, un peu plus rapide.
		 *
		 *****************************************************/
		FlushViewOfFile( ptr, 0UL ); /* 0 car on flush tout */
		UnmapViewOfFile( ptr ); /* décharge la map */
	}
	else
	{
		error = GetLastError();
	}

	/* ferme la map */
	CloseHandle( map );

	if ( NO_ERROR == error )
	{
		/* modifie la taille du fichier si aucune erreur */
		/* taille du fichier moin les octets retirés */
		return SetFileSize( pHandle, (fs.QuadPart - count) );
	}

	return error;

}

int main( int argc, char * argv[] )
{

	void * hFile; /* handle du fichier */
	char fname[] = ".\\testfile.txt"; /* nom du fichier à ouvrir/modifier */

	/* ouverture/création du fichier */
	hFile = CreateFile( 
					fname, 
					GENERIC_READ|GENERIC_WRITE, /* accès en écriture obligatoire */
					0UL, /* aucun partage */
					NULL, /* aucun attribue de sécurité */
					/*OPEN_EXISTING*/CREATE_ALWAYS, /* cré/remplace le fichier */
					FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS, /* attribus/flags */
					NULL /* pas de template */
					);

	/* erreur? */
	if ( hFile == INVALID_HANDLE_VALUE )
	{
		printf("CreateFile(): %lu\n", GetLastError());
		return 0;
	}

	/* modifie la taille du fichier */
	printf("SetFileSize(): %lu\n", SetFileSize( hFile, MEGA_BIT ));

	/* retire les octets de 0+1tier jusqu'a 0+2tier */
	/* on retire 1tier du fichier(le centre/millieu du fichier) */
	printf("RemoveData(): %lu\n", RemoveData( hFile, (MEGA_BIT / 3), (MEGA_BIT / 3) ));

	/* ferme le fichier */
	CloseHandle( hFile );
	putc( '\n', stdout );

	return 0;

}


 Conclusion

Créé & testé sous Visual Studio 6/Windows 2000 Pro

Cet exemple démontre seulement comment `tronquer`
un fichier sans utiliser d'autres fichiers ou de tampons/buffers
temporaire, etc ... On ouvre le fichier, le modifie et le ferme, tout
simplement!




~(.:: NitRic ::.)~


 Historique

18 mai 2007 01:44:37 :
ajout des mots clés( Vous aussi, mettez vos sources à jour !!! Ajoutez les mots clés !!! )

 Sources du même auteur

COMMENT CALCULER LE TEMP D'EXÉCUTION DE CERTAINES FONCTIONS ...
Source avec Zip VSTACK ( EFFET DE PILE ) / TEMPLATE
Source avec Zip NENGINE ( MOTEUR DE RECHERCHE POUR FICHIER ) (UPDATE)
Source avec Zip NLIST ( TEMPLATE )
Source avec Zip NSTRING (UPDATE) VERSION 1.5

 Sources de la même categorie

Source avec Zip WIN32 TLS LENT par dguilmain
Source avec Zip VIDER ELEMENTS DE CORBEILLE WINDOWS7 (WIN64) par BruNews
Source avec Zip Source avec une capture FIND TEXT (WIN64) par BruNews
Source avec Zip DELETE DIRECTORY (WIN64) par BruNews
Source avec Zip ENUM DIRECTORY (WIN64) par BruNews

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture CLASSE GRAPH: GESTION DES GRAPHIQUES DANS LES APPLICATIONS W... par Pistol_Pete
Source avec Zip NENGINE ( MOTEUR DE RECHERCHE POUR FICHIER ) (UPDATE) par NitRic
Source avec Zip MODIF OCTET FICHIER (WIN32) par BruNews
Source avec Zip GETOPENFILENAME & GETSAVEFILENAME, ... par NitRic
VÉRIFIER L'EXISTENCE D'UN FICHIER (SOUS WINDOWS(32/64) EXCLU... par NitRic

Commentaires et avis

Commentaire de angsthase le 04/04/2005 09:29:50

Tout d'abord merci nitric d'avoir fait cette source !!

Ensuite,  j'ai eux erreurs lors de la compil  :
     -  union large_integer has no member named low  part
     -  _ _________________________________high ___

???

Commentaire de NitRic le 04/04/2005 10:09:15

Okay, utilise ceci alors:

typedef union _LargeInteger
{
    struct
    {
        DWORD LowPart;
        LONG HighPart;
    };
    LONGLONG QuadPart;
}LargeInteger;


ensuite, remplace les `LARGE_INTEGER` par `LargeInteger`




~(.:: NitRic ::.)~

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Remplacer la copie de fichier de Windows [ par MangaII ] Salut !Quelqu'un sorai-t-il comment on pe remplacer la fonction de copie de fichier sous Windows par un programme maison !Mon but est d'optimiser la c Remplacer la fonction de copie de fichier sous Windows [ par MangaII ] Salut !Quelqu'un sorai-t-il comment on pe remplacer la fonction de copie de fichier sous Windows par un programme maison !Mon but est d'optimiser la c Ouvrir un fichier à la "Windows" [ par CyberP ] Comment afficher la boite de dialogue de choix de fichier classique de windows ? (ex : dans Word, si l'on fait fichier -&gt; ouvrir, une boite de dial Ourir Fichier Windows/Linux [ par jockos ] Bonjour,Je voudrais connaitre la meilleur méthode pour ouvrir des fichiers en C++ afin d'être compatible Windows/Linux.Jusque là, j'utilisais les API rechercher une string dans un fichier sous windows [ par doudblast ] voilà : l'idée est de récuperer une ip dans un fichier txtpar contre cette ip ne sera pas toujours la même et ne sera pas toujours précisemment au mêm Comment ouvrir la fenetre Windows "Ouvrir Fichier" en C++ ? [ par Pol Hochon ] Salut !J'ai un problème pour un projet de C++.J'aimerais bien connaitre l'instruction en C++ quipermet d'ouvrir la boite de dialogue Windows "Ouvrir" Changez Attribut (Chmod) d'un fichier sous Windows [ par mike0419 ] bonjour , je cherche comment changez l'attribut (chmod)lecteur Seule d'un fichier pour le mettre en ecriture (enlevé le lecteur seule koi lol)voila me Compatibilité allegro-windows : les fonctions le l'API win32 [ par programmateur ] (Je reposte ce message à cause de problemes de connexion au cite qui m'empechent de repondre a la discution)Salut,Je poste simplement ce message pour Retour ligne dans un fichier (UNIX / Windows) [ par Clonk ] Bonjour,Voilà, j'ai un problème avec des fichiers. Ce sotn des fichiers texte générés sous UNIX que je dois traiter en C++ sous Windows (c'est comme ç fichier xls ouvert avec windows.h [ par ancat ] Salut Es ce que je peux recuperer le contenu d'un tableau excel en vc++?J'arrive a recuperer le contenu d'un fichier texte mais avec excel je ne recup


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 1,201 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales