Home | Chi sono | Contattami
 

Progr. lineare

Delphi
 
Componenti
  Database
 
Miei articoli

Windows

Miei articoli 

 

Componente e Programma per rinominare tutti i file il cui nome contiene caratteri diversi da cifre, lettere ed underscore ("_") sostituendo tali caratteri con un underscore


Spesso ci si trova ad avere dei file il cui nome contiene qualsiasi tipo di carattere: in un contensto di rete che comprende sistemi operativi differenti, questo può causare problemi in quanto sistemi operativi diversi da Windows possono non accettare nomi di file con certi caratteri. Allora ho voluto creare un programma che, data una cartella di partenza, scansioni ricorsivamente tutte le cartelle, sottocartelle e file, e rinomini tutti quelli che contengono caratteri non alfanumerici sostituendo questi ultimi con un underscore ("_"). Vediamo nel seguito la realizzazione.

1. Componente

Tanto per cominciare ho preso in esame la procedura ricorsiva di scansione di cartelle, sottocartelle e file. Mi è venuto in aiuto l' ottimo componente all' indirizzo

http://delphi.about.com/library/weekly/aa052300a.htm

A questo punto mi sono detto: se inserissi un evento nella parte di codice in cui viene restituito il nome della cartella o del file di turno, allora nell' implementazione di tale evento, potrei inserire quelle "due" righe di codice che mi permettono di rinominare la cartella o il file nel modo che voglio io. Detto fatto, ecco il codice del componente modificato

unit FindFile; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, FileCtrl; type TFileAttrKind = (ffaReadOnly, ffaHidden, ffaSysFile, ffaVolumeID, ffaDirectory, ffaArchive, ffaAnyFile); TFileAttr = set of TFileAttrKind; TFileFound = procedure (var Rec: TSearchRec; InPath: string) of object; TFindFile = class(TComponent) private FFileFound: TFileFound; //questo l' ho aggiunto io s : TStringList; fSubFolder : boolean; fAttr: TFileAttr; fPath : string; fFileMask : string; procedure SetPath(Value: string); procedure FileSearch(const inPath : string); public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function SearchForFiles: TStringList; published property FileAttr: TFileAttr read fAttr write fAttr; property InSubFolders : boolean read fSubFolder write fSubFolder; property Path : string read fPath write SetPath; property FileMask : string read fFileMask write fFileMask ; property OnFileFound: TFileFound read FFileFound write FFileFound; //questo l' ho aggiunto io end; procedure Register; implementation procedure Register; begin RegisterComponents('Carlo Pasolini', [TFindFile]); end; constructor TFindFile.Create(AOwner: TComponent); begin inherited Create(AOwner); Path := IncludeTrailingBackslash(GetCurrentDir); FileMask := '*.*'; FileAttr := [ffaAnyFile]; s := TStringList.Create; end; destructor TFindFile.Destroy; begin s.Free; inherited Destroy; end; procedure TFindFile.SetPath(Value: string); begin if fPath <> Value then begin if Value <> '' then if DirectoryExists(Value) then fPath := IncludeTrailingBackslash(Value); end; end; function TFindFile.SearchForFiles: TStringList; begin s.Clear; try FileSearch(Path); finally Result := s; end; end; procedure TFindFile.FileSearch(const InPath : string); var Rec : TSearchRec; Attr : integer; FileName: string; begin Attr := 0; if ffaReadOnly in FileAttr then Attr := Attr + faReadOnly; if ffaHidden in FileAttr then Attr := Attr + faHidden; if ffaSysFile in FileAttr then Attr := Attr + faSysFile; if ffaVolumeID in FileAttr then Attr := Attr + faVolumeID; if ffaDirectory in FileAttr then Attr := Attr + faDirectory; if ffaArchive in FileAttr then Attr := Attr + faArchive; if ffaAnyFile in FileAttr then Attr := Attr + faAnyFile; if SysUtils.FindFirst(inPath + FileMask, Attr, Rec) = 0 then try repeat // questo l' ho aggiunto io if assigned(OnFileFound) then OnFileFound(Rec, InPath); // s.Add(inPath + Rec.Name); until SysUtils.FindNext(Rec) <> 0; finally SysUtils.FindClose(Rec); end; If not InSubFolders then Exit; if SysUtils.FindFirst(inPath + '*.*', faDirectory, Rec) = 0 then try repeat if ((Rec.Attr and faDirectory) > 0) and (Rec.Name<>'.') and (Rec.Name<>'..') then begin FileSearch(IncludeTrailingBackslash(inPath + Rec.Name)); end; until SysUtils.FindNext(Rec) <> 0; finally SysUtils.FindClose(Rec); end; end; end.

2. Programma

Ok ora abbiamo un componente di scansione ricorsiva di cartelle, sottocartelle e file con un evento che si verifica ogni volta che viene restituita una cartella od un file. Resta solo da creare un programmino che utilizzi tale componente: per semplicità vado a descrivere l 'implementazione dell' evento OnFileFound

procedure TFrmRenFiles.FindFile1FileFound(var Rec: TSearchRec; InPath: String); var i: integer; FileName: string; NewFileName: string; begin if ((Rec.Name <> '.') and (Rec.Name <> '..')) then begin FileName := Rec.Name; NewFileName := ''; for i := 1 to Length(FileName) do if not (FileName[i] in ['0'..'9', 'a'..'z', 'A'..'Z', '_', '-', '.']) then NewFileName := NewFileName + '_' else NewFileName := NewFileName + FileName[i]; Rec.Name := NewFileName; if NewFileName <> FileName then begin RenameFile(InPath + FileName, InPath + NewFileName); end; end; end;

3. Piccole .. note.

Questo programma l' ho usato tante volte senza avere problemi, chiunque lo voglia usare deve però verificare che sia corretto (insomma se lo usate e fate dei danni sono cazzz.... vostri, ...). Un' altra nota: se avete salvato delle pagine internet come "Pagina Web, completa (*.htm, *.html)" allora se vengono rinominati i file immagine, etcc.. , questi poi non saranno più visibili aprendo al pagina salvata, in quanto dovrebbero essere riniominati anche i link all' interno della pagina. E' per questo che è meglio prendere l' abitudine di salvare come "Archivio Web, file unico (*.mht)"

Componente    Rename.7z
 

 
 
Your Ad Here