Newsgroup: it.comp.lang.c++
Titolo: Problemi con il trattamento di file e directory

Ciao a tutti,
	se ho una directory piena non posso usare il RemoveDirectory
	per cancellarla. Ora, pero', se non conosco esattamente cio' che
	e' presente nella dir non posso cancellarlo con il DeleteFile
	o con il CFile::Remove().
	Quindi, come faccio a cancellare una directory piena di file
	di cui non conosco il nome?
	Grazie a tutti.
	Bye
	    Enrico

 di cui non conosco il nome?
Scoprendo i nomi di tutti i file che essa contiene grazie a
FindFirstFile/FindNextFile/FindClose, e cosi` sapendo
cosa DeleteFile'are...!-)  A livello di API, non credo proprio
ci sia altro modo.
Alex

Penso tu debba impostare un ciclo in cui ti cancelli file per file. Per
sapere i nomi dei file, e ti trovi su un PC, dovrebbero esserci le
funzioni findfirst e findnext.
Flavio
--
Ing. Flavio Poletti
STS s.r.l.
Via Odoardo Beccari, 13
00154 Roma, Italia
Tel. +39 6 5755096
FAX  +39 6 57287214
company e-mail: 
sts...@tin.it
private e-mail: 
pol...@writeme.com

ci sia altro modo.
E infatti ho provato a fare questo, pero' mi ritorna sempre un
INVALID_HANDLE_VALUE, quindi un fallimento nell'operazione. Eppure 
la directory specificata è quella corretta. La sintassi che ho usato e' la
seguente
	CString CompletePath;	// Directory da cancellare 
	HANDLE hf;
	LPWIN32_FIND_DATA df;
	hf = FindFirstFile(CompletePath,df);
Ho provato anche a mettere come directory direttamente "*" oppure
"C:", con lo stesso risultato. 
Non mi sembra di aver sbagliato nulla. Cosa ne dite? Esiste forse un
modo particolare di scrivergli la directory?
Bye
Enrico

modo particolare di scrivergli la directory?
Mi sembra di capire che i tuoi errori sono due, uno "occasionale"
e leggero (ma di per se sufficiente a spiegare il malfunzionamento),
l'altro grave, concettuale, fondamentale, che e` importante capire
e correggere anche e soprattutto per evitare disastri futuri, non solo
in questa chiamata, ma in qualsiasi altra delle API Win32 e di tante
altre librerie, sia C, sia C++.
Anzitutto, il primo argomento: questo deve essere una "maschera",
comprendente, dopo il directory che ti interessa, un backslash
seguito da *.* se vuoi trovare tutti i contenuti del directory stesso;
se passi solo il nome del directory, troverai, appunto, solo il
directory in questione.  Insomma, concatena "\\*.*" alla tua stringa
di path (nota: la \ raddoppiata per ragioni di sintassi C!).
Ma il problema serio e` il secondo argomento.  Esso e` un pointer
ad una struttura di tipo WIN32_FIND_DATA -- e infatti tu passi un
valore di questo tipo; ma passi il valore di una variabile *NON*
inizializzata, praticamente un valore "casuale".  Presumibilmente,
per tua (relativa) fortuna, sara` stato uno zero o qualcosa comunque
tale che Windows ha potuto capire come "puntatore non valido",
quindi la chiamata sara` fallita per "invalid pointer" (non possiamo
sapere perche` fallisce, se non chiami GetLastError subito dopo
avere ricevuto l'handle che ti informa del fallimento); il caso grave
sarebbe quello in cui questo "puntatore impazzito" si trovasse, per
caso, a indicare una zona di memoria scrivibile ma del tutto priva
di alcuna relazione con checchessia -- questo ti sovrascriverebbe
un pacco di variabili tue producendo errori assolutamente qualsiasi
in un momento successivo del programma!!!
Da capire e ricordare: tutte le volte che una chiamata Win32 (o di
una qualsiasi altra libreria chiamabile da C) prende fra i propri
argomenti un puntatore (in Win32, questo e` spesso indicato da
nomi di tipi che iniziano con le lettere LP), bisogna passarle un
puntatore correttamente inizializzato!!!  Leggere la documentazione
della routine per i dettagli, ma in generale andra` bene l'indirizzo di
una propria struttura del tipo richiesto.
Ecco un esempio di uso delle FindFirstFile, ecc, che praticamente
emula una piccola DIR (col vantaggio di poterle passare molteplici
argomenti:-): e` un programma di console, scritto naturalmente in C:
-- inizio taglio: mydir.c
#include <windows.h>
#include <stdio.h>
void
findall(const char *nom)
{
    WIN32_FIND_DATA wfd;
    HANDLE h = FindFirstFile(nom, &wfd);
    if(h==INVALID_HANDLE_VALUE) {
        printf("Not found: %s\n", nom);
        return;
    }
    for(;;) {
        printf("Found: %s\n", wfd.cFileName);
        if(!FindNextFile(h, &wfd)) {
            FindClose(h);
            return;
        }
    }
}
int main(int arcg, const char *argv[])
{
    int i;
    for(i=1; i<arcg; ++i)
        findall(argv[i]);
    return 0;
}
-- fine taglio: mydir.c
Una volta compilato, chiamando ad esempio:
    mydir .
si otterra` il nome del directory corrente, mentre:
    mydir .\*.*
dara` l'elenco dei file che esso contiene (qui NON
occorre raddoppiare il \ -- il suo uso nella sintassi
C, infatti, non entra qui in gioco, visto che esso non
si trova fra i sorgenti del nostro programma ma fra
gli argomenti che il programma riceve "da fuori").
Piccole modifiche a questo programma ti permetteranno
di esplorare la struttura WIN32_FIND_DATA e i vari
campi che essa contiene, tipo gli attributi dei vari file
(visto che tu vuoi cancellarli, dovrai esaminare e, se serve,
resettare l'eventuale flag di "read-only"; se trovi altri
directory entro quello che vuoi rimuovere, dovrai poi
recursivamente esaminarli e rimuovere prima i file in
essi contenuti; ecc, ecc).
Facci sapere se hai risolto, o se ti servono altri aiuti
e consigli...!
Alex

Ringrazio Alex e Flavio. Ora funziona!
Comunque, il path che passavo come parametro era:
	CompletePath.Format("%s\\T*.bmp",DPath);
	con DPath = "C:\\Analisi\\Archivio\\Bmp"
quindi corretto. I casi da me riportati erano quelli
estremi, dovuti alla disperazione dopo l'ennesimo
tentativo razionale fallito. Comunque il problema stava
effettivamente, come Alex aveva suggerito, nel passaggio
del secondo parametro (con "&"). E ora mi spiego anche
alcuni problemi di "wild pointer" avuti in precedenza.
Vorrei chiedere un favore ad Alex (visto che Flavio ha gia' risposto).
C'e' una mia News dal titolo "DataBase Access non rimuovibili". Potresti dare
un'occhiata? Anche li' immagino sia un errore stupido da parte mia. Mah?!
Grazie ancora.
Bye
Enrico