Benvenuto Visitatore ( Log In | Registrati )
![]() ![]() |
5 Sep 2008, 17:12
Messaggio
#1
|
|
|
Level 3/11 ![]() ![]() ![]() Gruppo: Forum User + Messaggi: 119 Iscritto il: 6-April 05 Da: Pinerolo Utente Nr.: 3.498 |
Descrizione del problema
---------------------------- Ho i dischi xraid del xserve ormai quasi pieni (5TB). I dati contenuti sono strutturati in cartelle "logiche", esempio LavoriFatti -> Prodotti -> Persone -> Files utente. Non posso mettermi a masterizzare tutto a parte i costi ci vorrebbe un sacco di tempo. Devo quindi trovare un sistema che mi sposti tutti i files "vecchi" ossia compresi in un intervallo di tempo che decido io su altri dischi. Lo spostamento pero' deve ricreare la stessa struttura logica delle cartelle di origine e mantenerle anche sui dischi originali (anche se vuoti). Soluzione pensata -------------------- Mi faccio un programmello che mi fa scegliere il periodo da elaborare, (dal - al) , le cartelle iniziali da cui iniziare a spostare i dati e la cartella di destinazione in cui mettere man mano che li trovo i vari files. Procediamo ------------- Definizione dell'interfaccia grafica con Interface Builder, mi servono: due controlli di tipo calendario (per far scegliere il periodo dal/al) una NSTableView per memorizzare temporaneamente l'elenco delle cartelle che voglio analizzare per effettuare lo spostamento dati e di conseguenza un pulsante NSButton per AGGIUNGERE un nuova cartella ed il pulsante RIMUOVI Mi serve un NSTextField per scriverci il percorso della cartella di destinazione in cui spostare i dati ed anche un pulsante per evitare di far scrivere il percorso ma di poterlo selezionare facendo SFOGLIA. Sino a qui, i controlli per ottenere i dati che l'utente mi deve indicare. Poi ci metto un pulsante per AVVIARE LO SPOSTAMENTO, una NSProgressIndicator per visualizzare che l'operazione e' in corso, un pulsante INTERROMPI per fermare l'operazione di spostamento ed infine un NSTextField per visualizzare informazioni all'utente durante l'esecuzione del processo. Una volta definita l'interfaccia, creo la mia classe controller e realizzo le necessarie connessioni ed ottengo i due files FGController.h e FGController.m COMPLICAZIONE 1 ============ Per poter far in modo che l'interfaccia utente sia "responsiva" durante l'operazione di SPOSTAMENTO (che puo' esssere ovviamente anche mooooolto lunga) devo "svincolare" la gestione dell'interfaccia dall'esecuzione del compito di "SPOSTARE I FILES". Per fare cio', uso un Thread separato (tipicamente indicato con il termine di worker thread) utilizzando un metodo dell'oggetto NSThread messo a disposizione da Cocoa. Creo una nuova classe che si occupera' di effettuare le operazioni di spostamento dei dati (FGMoveFiles.h e FGMoveFile.m). Devo quindi istanziare un oggetto basato su tale classe e mandero' in esecuzione un metodo di questo nuovo oggetto che effettuera' le operazioni CODE ( -(void) makeMove:(NSArray *) theArgs; ) Come si vede dal prototipo di chiamata del metodo makeMove, passo ad esso ancge un array, in modo da poter passare degli argomenti al metodo, in pratica passo come argomento l'oggetto FGController, in quanto l'oggetto FGMoveFile deve "conoscerlo" per poter chiamare determinati metodi in particolare per aggiornare le informazioni per l'utente. Praticamente quando premo il pulsante AVVIA SPOSTAMENTO eseguo un nuovo thread con le seguenti istruzioni CODE NSArray * theArgs = [NSArray arrayWithObjects: self, nil]; [NSThread detachNewThreadSelector:@selector(makeMove:) toTarget:threadFgMoveFiles withObject: theArgs]; In pratica creo prima un array a cui associo un oggetto che e' l'oggetto chiamante (FGController) per interderci e poi passo questo array all' oggetto TARGET del metodo detachNewThreadSelector (l'oggetto di tipo FGMoveFile) in modo che venga passato come argomento alla chiamata del metodo makeMove Quindi riepilogando: L'oggetto che e' il controller dell'interfaccia (di tipo FGController) ha nell'elenco dei suoi membri un oggetto di tipo FGMoveFile CODE @interface FGController : NSObject { IBOutlet NSButton *addBytton; IBOutlet NSButton *browseDestButton; IBOutlet NSProgressIndicator *prgBar; ... ... FGMoveFiles *threadFgMoveFiles; //OGGETTO che si occupa del "LAVORO DI SPOSTAMENTO DATI" } ... ... quando premo Avvia Spostamento, viene creato un nuovo thread che richiama il metodo makeMove dell'oggetto threadFgMoveFiles passando come argomento self (ossia il puntatore all'oggetto FGController). OPERAZIONI DI SPOSTAMENTO ==================== In sintesi l'operazione di spostamento di traduce in Per ogni cartella da elaborare indicata in precedenza Ricava l'elenco dei files e delle altre sottocartelle Se e' una cartella, non spostare nulla Se e' un file, leggi la data di modifica Se e' nell'intervallo indicato in precedenza dall'utente, allora SPOSTA il file (lo spostamento consiste nella COPIA del FILE e se non vi sono stati errori alla CANCELLAZIONE DELL'ORIGINALE) ::::::::::::::::::::: :::IMPORTANTE:::: ::::::::::::::::::::: Questa utility CANCELLA DEI FILES, quindi prima di utilizzarla su dati IMPORTANTI vi suggerisco di VERIFICARNE il corretto funzionamento. NON MI RITENGO ASSOLUTAMENTE RESPONSABILE PER EVENTUALI PERDITE DI DATI DOVUTI ALL'USO DI TALE UTILITY. COMPLICAZIONE 2 ============ Dato che questa utility e' stata pensata per essere usata sul un server, e' probabile che sul server esistano degli utenti e dei permessi associati ai files dei vari utenti. Di conseguenza, mentre l'operazione di COPIA e' consentita (a meno che un certo file/cartella non presenti neanche il permesso di lettura) l'operazione di CANCELLAZIONE richiede un permesso di modifica dei files, che nel caso in cui il files sia di proprieta' di uno specifico utente e che il permesso di lettura e scrittura sia associato solo a tale utente (owner) occorrerà essere amministratori (root) per poter cancellare files di altri utenti. Per evitare di dover fare eseguire tale utiliy in modalità root, ho implementato il meccanismo di autorizzazione per consentire all'utility di impersonare il "root" durante l'operazione di cancellazione. A tale funzione servono le chiamate AuthorizationCreate, preauthorizeForRight, runCommandWithAutorization ecc. ma consiglio a chi fosse interessato di approfondire l'argomento cercando info su internet o su libri. Il seguente link http://www.disco.germinara.it/FGArchive.zip contiene l'applicazione ed il seguente il progetto completo in xcode 2.4.1 http://www.disco.germinara.it/FGArchiveSrc.zip Essendo una "condivisione di idee", sono ovviamente ben accette tutte le vostre considerazioni in merito. Grazie per l'attenzione. Francesco Germinara |
|
|
|
|
|
|
5 Sep 2008, 17:46
Messaggio
#2
|
|
|
Bel tutorial e brillante soluzione!
Mi chiedevo: quando avvii il nuovo thread e passi l'NSArray contenente gli argomenti, forse potresti addirittura usare una soluzione ancor più generale, ovvero passare un NSDictionary, che avrebbe il pregio di identificare i vari tipi di argomenti "per nome" anziché "per posizione" nell'array, e permetterebbe in un futuro, dovesse servire, di passare non solo oggetti, ma anche altre array o dizionari. Mi rendo conto che per lo scopo per cui nasce questa applicazione magari questo è un overhead fin eccessivo, e infatti la mia non era una critica, era solo uno spunto di discussione per capire se poteva essere una cosa furba da fare, oppure no. Grazie! -------------------- Marco Coïsson
http://homepage.mac.com/marco_coisson L'atomo divisibile: podcast gratuito di divulgazione scientifica. X come Macintosh |
|
|
|
|
8 Sep 2008, 11:11
Messaggio
#3
|
|
|
Level 3/11 ![]() ![]() ![]() Gruppo: Forum User + Messaggi: 119 Iscritto il: 6-April 05 Da: Pinerolo Utente Nr.: 3.498 |
Bel tutorial e brillante soluzione! Mi chiedevo: quando avvii il nuovo thread e passi l'NSArray contenente gli argomenti, forse potresti addirittura usare una soluzione ancor più generale, ovvero passare un NSDictionary, che avrebbe il pregio di identificare i vari tipi di argomenti "per nome" anziché "per posizione" nell'array, e permetterebbe in un futuro, dovesse servire, di passare non solo oggetti, ma anche altre array o dizionari. Mi rendo conto che per lo scopo per cui nasce questa applicazione magari questo è un overhead fin eccessivo, e infatti la mia non era una critica, era solo uno spunto di discussione per capire se poteva essere una cosa furba da fare, oppure no. Grazie! Ciao Marco, Grazie. Sicuramente di puo' usare un NSDictionary che rende di sicuro anche piu' leggibile il codice (es. non devo "sapere" che il primo elemento dell'array e' un cero oggetto piuttosto che un altro ecc.", ma essendo la necessità cosi' limitata in questo mio codice (passo solo un oggetto) ho optato per una passaggio diretto dell'oggetto. |
|
|
|
8 Sep 2008, 14:01
Messaggio
#4
|
|
|
Sicuramente di puo' usare un NSDictionary che rende di sicuro anche piu' leggibile il codice (es. non devo "sapere" che il primo elemento dell'array e' un cero oggetto piuttosto che un altro ecc.", ma essendo la necessità cosi' limitata in questo mio codice (passo solo un oggetto) ho optato per una passaggio diretto dell'oggetto. Capisco perfettamente. Infatti il mio era solo uno spunto di discussione, anche per imparare qualche cosa di nuovo e capire se la "tecnica del dizionario", come la chiamo io, è una cosa sensata e che la gente usa, o è una stupidaggine che mi è venuta in mente tempo fa e che ho usato in qualche occasione (non dimenticare che sono autodidatta e non ho mai studiato né frequentato corsi di programmazione, quindi cose ovvie e straconosciute sono per me delle grandi scoperte, quando ci arrivo per conto mio). -------------------- Marco Coïsson
http://homepage.mac.com/marco_coisson L'atomo divisibile: podcast gratuito di divulgazione scientifica. X come Macintosh |
|
|
|
|
12 Sep 2008, 00:05
Messaggio
#5
|
|
|
Io, per la poca esperienza che ho, la tecnica del dizionario la uso sempre se possibile.
Per me equivale agli hash in ruby, per esempio; è comodo avere array indicizzato con stringhe. Davide -------------------- |
|
|
|
|
17 Sep 2008, 09:15
Messaggio
#6
|
|
|
Soluzione notevole, quando ho 5 minuti me la leggo bene bene.
-------------------- Emanuele Personale | Blog | Facebook | LinkedIn
Supporta Tevac! "The competent programmer is fully aware of the limited size of his own skull. He therefore approaches his task with full humility, and avoids clever tricks like the plague." - Edsger W. Dijkstra |
|
|
|
|
![]() ![]() |
| Titolo discussione | Risposte | Autore discussione | Visite | Ultima azione | |||
|---|---|---|---|---|---|---|---|
![]() |
937 | Opel1972 | 48.964 | 26 November 2008 - 23:23 Ultimo messaggio di: francesco59 |
|||
![]() |
3 | kore | 150 | 22 November 2008 - 16:03 Ultimo messaggio di: ugo |
|||
![]() |
6 | ryosaeb4 | 125 | 20 November 2008 - 20:54 Ultimo messaggio di: Max31055 |
|||
![]() |
0 | TevacPhoto | 60 | 9 November 2008 - 18:55 Ultimo messaggio di: TevacPhoto |
|||
![]() |
42 | asilipo | 870 | 30 October 2008 - 22:15 Ultimo messaggio di: jeriko1kenobi |
|||
![]() |
5 | stralunato | 129 | 30 October 2008 - 01:48 Ultimo messaggio di: Roberto Rota |
|||
![]() |
8 | iMik | 156 | 22 October 2008 - 17:06 Ultimo messaggio di: iMik |
|||
![]() |
2 | Francesco Schiavon | 232 | 20 October 2008 - 06:52 Ultimo messaggio di: supervolt |
|||
![]() |
0 | TevacPhoto | 29 | 18 October 2008 - 17:09 Ultimo messaggio di: TevacPhoto |
|||
![]() |
0 | TevacPhoto | 23 | 18 October 2008 - 17:09 Ultimo messaggio di: TevacPhoto |
|||
![]() |
31 | fc2 | 249 | 18 October 2008 - 09:31 Ultimo messaggio di: fc |
|||
![]() |
4 | Gojca | 197 | 16 October 2008 - 09:29 Ultimo messaggio di: Gojca |
|||
|
Versione Lo-Fi | Oggi è il: 2 December 2008 - 02:52 |
| IP.Board Skin Developed By Creative Networks | ||