Avatar billede mcnovy Nybegynder
23. maj 2006 - 21:34 Der er 20 kommentarer og
1 løsning

Fil indeksering

Hej

er der nogle der kender nogle gode metoder til at holde et fil index (vil jeg tro det skal hede)

ideen er at jeg skal have en thread til at kører hver gang et program starter.!
det den så skal gøre er at finde ud af om der er nogle filer i mappen, eller filer i undermapperne som er blevet ændret, slettet, eller om der er oprettet noget nyt siden sidst..!

nogle der har gode forslag...?

min egen idé var at bruge
System.IO.FileInfo.LastWriteTime
og så kører den på mappen, og dens undermapper..!

men er der nogen der har bedre forslag??
Avatar billede Lasse Novice
23. maj 2006 - 22:45 #1
Hvad med at kigge paa klassen filesystemwatcher. Med denne klasse kan du faa events naar der sker aendringer.
Avatar billede Syska Mester
23. maj 2006 - 23:13 #2
Hans problem er vel at programmet ikke kører hele tiden, og derfor skal gemme et index over alle filer der er der nu, og så sammen holde det med det nye index der bliver lavet næste gang programmet startes....

// ouT
Avatar billede nielle Nybegynder
24. maj 2006 - 10:55 #3
En given løsning skal vel også kunne tage højde for at der er filer som er blevet slettet siden sidst?
Avatar billede mcnovy Nybegynder
24. maj 2006 - 20:50 #4
der er åbenbart lidt misforståelser :)

buzzzz. korrekt.. programmet vil ikke kører konstant.
nielle, som skrevet i spørgsmålet..

programmet skal tage højde for både om mapper og om filer bliver ændret, oprettet, eller slettet.

en lille struktur

C:\HovedMappe
C:\HovedMappe\Fil_1.Fil
C:\HovedMappe\Fil_2.Fil
C:\HovedMappe\Fil_3.Fil

C:\HovedMappe\UnderMappe1\1_Fil_1.Fil
C:\HovedMappe\UnderMappe1\1_Fil_2.Fil
C:\HovedMappe\UnderMappe1\1_Fil_3.Fil

C:\HovedMappe\UnderMappe2\2_Fil_1.Fil
C:\HovedMappe\UnderMappe2\2_Fil_2.Fil
C:\HovedMappe\UnderMappe2\2_Fil_3.Fil

C:\HovedMappe\UnderMappe3\3_Fil_1.Fil
C:\HovedMappe\UnderMappe3\3_Fil_2.Fil
C:\HovedMappe\UnderMappe3\3_Fil_3.Fil

ting den skal kunne se kunne være:

C:\HovedMappe\Fil_1.Fil
C:\HovedMappe\Fil_2.Fil
C:\HovedMappe\Fil_3.Fil

C:\HovedMappe\UnderMappe1\1_Fil_1.Fil
C:\HovedMappe\UnderMappe1\1_Fil_2.Fil
C:\HovedMappe\UnderMappe1\1_Fil_3.Fil

C:\HovedMappe\UnderMappe2\2_Fil_1.Fil
C:\HovedMappe\UnderMappe2\2_Fil_3.Fil
C:\HovedMappe\UnderMappe2\enNYfil.Fil

C:\HovedMappe\UnderMappe3\3_Fil_1.Fil
C:\HovedMappe\UnderMappe3\3_Fil_5610.Fil
C:\HovedMappe\UnderMappe3\3_Fil_3.Fil

dvs filen
C:\HovedMappe\UnderMappe2\2_Fil_2.Fil
er slettet
C:\HovedMappe\UnderMappe2\enNyfil.Fil
er blevet oprettet
C:\HovedMappe\UnderMappe3\3_Fil_5610.Fil
navnet er blevet ændret. (og det gælder også indholdet i filen)

dvs ALLE ændringer i mappen, OG undermapper (og mapperne i sig selv)
skal "opdages"
Avatar billede Lasse Novice
24. maj 2006 - 21:31 #5
Lav en flad database fil, hvor indholdet bliver:

C:\HovedMappe\Mappe|LastModifiedDate|1
C:\HovedMappe\Fil_1.Fil|LastModifiedDate|0
C:\HovedMappe\Fil_2.Fil|LastModifiedDate|0
C:\HovedMappe\Fil_3.Fil|LastModifiedDate|0
C:\HovedMappe\UnderMappe1\1_Fil_1.Fil|LastModifiedDate|0
C:\HovedMappe\UnderMappe1\1_Fil_2.Fil|LastModifiedDate|0
C:\HovedMappe\UnderMappe1\1_Fil_3.Fil|LastModifiedDate|0
C:\HovedMappe\UnderMappe2\2_Fil_1.Fil|LastModifiedDate|0
C:\HovedMappe\UnderMappe2\2_Fil_3.Fil|LastModifiedDate|0
C:\HovedMappe\UnderMappe2\enNYfil.Fil|LastModifiedDate|0
C:\HovedMappe\UnderMappe3\3_Fil_1.Fil|LastModifiedDate|0
C:\HovedMappe\UnderMappe3\3_Fil_5610.Fil|LastModifiedDate|0
C:\HovedMappe\UnderMappe3\3_Fil_3.Fil|LastModifiedDate|0

LastModifiedDate er den dato filen sidst er blevet aendret... sidste gang du checkede. 0 eller 1 tilsidst beskriver om det er en fil eller en mappe.

Du checker pseudokode agtigt saaledes (Der mangler lidt paa mappe checkningen, men det kan du nok selv finde ud af):

public class FileOrFolder
{
  public DateTime OldLastModifiedDate;
  public DateTime NewLastModifiedDate;

  public bool NewFound;

  public bool IsFile; /* If not it is folder */

  public FileOrFolder()
  {
  }
}

public void Check()
{
  Dictionary<string, File> mFilesAndFolders = new Dictionary<string, File>();

  foreach(string line in file)
  {
    string filePath = line.split('|')[0];
    string lastModifiedDate = line.split('|')[1];
    bool isFile = line.split('|')[2] == "0";
    File file = new File();
    file.OldLastModifiedDate = System.DateTime.Parse(lastModifiedDate);
    file.IsFile = isFile;
    mFilesAndFolders.Add(filePath, file);
  }

  foreach(string filePath in System.IO.Directory.GetFiles("*.*", IncludeSubFolders))
  {
    if(!mFilesAndFolders.Contains(filePath)) { /* FILE ADDED */}
 
    mFilesAndFolders[filePath].NewFound= true;
    mFilesAndFolders[filePath].NewLastModifiedDate = System.IO.File.GetLastModifiedDate(filePath);
  }

  foreach(string filePath in mFiles.Keys)
  {
    if(!mFilesAndFolders[filePath].NewFound) {/* FILE DELETED */}

    if(mFilesAndFolders[filePath].NewLastModifiedDate > mFilesAndFolders[filePath].OldLastModifiedDate) { /* FILE CHANGED */ }
  }
}

Efter check gemmer du filen igen saaledes (Der mangler lidt paa mappe gemningen, men det kan du nok selv finde ud af):

public void PersistFile(filePath)
{
  filestream = OpenFileForWrite(filePath);

  foreach(string filePath in System.IO.Directory.GetFiles("*.*", IncludeSubFolders))
  {
    filestream.WriteLine(filePath + "|" + System.IO.File.GetLastModifiedDate(filePath) + "|0" );
  }

  filestream.Close();
}
Avatar billede mcnovy Nybegynder
24. maj 2006 - 22:17 #6
set med det halve øje.

vil denne kode ikke tjekke hver enkelte fil..?

kunne man ikke nøjes med at tjekke om der har været ændringer i mappen..?

det der kode ligner noget kode som vil suge en del resourcer..!
og dem skal der spares MEGET på..!
Avatar billede Lasse Novice
24. maj 2006 - 23:02 #7
Ok, jeg laeser din sidste kommentar som om der er MANGE filer, sandt?

Jeg tror ikke du kan faa at vide om der er sket aendringer i mappen.

Dog syntes jeg stadig at det ville vaere MEGET smartere at bruge filesystemwatcher i en service der koerer i baggrunden. Her sparer du resourcer. Du skal selvfoelgelig stadig lave checket hver gang servicen stoppes og startes, men det skulle jo kun ske ved maskine start og stop. Desuden gaar checket meget hurtigt mm. du har en million filer.
Avatar billede mcnovy Nybegynder
24. maj 2006 - 23:09 #8
Ja, rimelig mange filer ja.!

det med et filesystemwatcher er jo ikke nogen dårlig idé, set i lyset af at der jo ikke kan ske mange ændringer med mappen, når computeren er slukket.. :)
Avatar billede md_craig Nybegynder
26. maj 2006 - 23:23 #9
Skal lige hører om du evt. har mulighed for at bruge en "Rigtig" database da det med mange filer måske bliver lidt mere hensigtsmessigt... og jow... du skulle i princpet kunne scanne mapper, og så kun scanne filer i den mappe hvis ændringsdatoen på mappen har ændret sig da DirectoryInfo også har en "Sidst ændret parameter"

Hvis du ikke har adgang til en DB, ville jeg nok lave en bnær fil istedet og indrette den væsentligt anderledes således at du fx lister alle mapper først, med "Byte indexes" til deres filer eller noget i den stil...

Da jeg vil mene dette vil kunne give dig ydelsesfordele når du skal læse filen igennem... kan godt lige kigge på et eksempel...
Avatar billede mcnovy Nybegynder
26. maj 2006 - 23:56 #10
min tanke var enten en db, eller en txt fil, det negative ved db filen er at jeg er bange for at den vil bruge ekstra ressurcer..!

men om det er en db eller en txt fil, eller binært., så vil det være et dynamisk data"felt"

men jeg har mulighed for at gøre som det passer mig, da jeg jo selv styre systemet..! :)

men nogle gode råd til det mindst ressurce krævende..?
Avatar billede md_craig Nybegynder
27. maj 2006 - 00:09 #11
Mja... det kommer an på hvordan du mener "ressurce" krævende...

Det tager lang tid?
Det taget meget disk plads?
Det tager mange ram?

Textbaseret fil vil nok være det værste du kan vælge...

Valget mellem en binær fil vs. db er måske lidt svæere... det kan være langsommere at kører sådan en fil igennem og finde ændringer, men måske kræve fæere ram/disk...
Avatar billede mcnovy Nybegynder
27. maj 2006 - 00:16 #12
Disc pladsen er ikke helt så vigtig.. (selvfølgelig inden for en rimelig grænse :) )
det er ram og cpu power der betyder noget.!
Avatar billede md_craig Nybegynder
27. maj 2006 - 00:38 #13
Hehe... det gjorde det faktisk ikke nemmere at svarer på :P...

men et eller andet sted vil jeg måske tro du skal prøve dig frem med en binær fil, for du skal allivevel igennem det hele, så mon ikke det i sidste ende bliver den bedste løsning...

(Folk må jo råbe højt hvis de er uenige :P)

Det bliver der dog en smule kode arbejde i, for der vil være bedst er at du laver din egen lille slags "database" ^^ som nævnt før...

du kan så vælge om du skal have statiske eller variable størelser på dine "felter"... eks:

Statisk eks: (A)
____________________________________________________________________________
Master folder:
1024 byte: (1000 byte path, 8 byte dato, 8 byte subdir liste startindex, 8 byte fil liste startindex)

Subfolders:
128 byte: (96 byte name, 8 byte dato, 8 byte masterdir index, 8 byte subdir liste startindex, 8 byte fil liste startindex)

Files:
128 byte: (104 byte name, 8 byte dato, 8 byte masterdir index, 8 byte fil liste startindex)



Dynamisk eks: (B)
____________________________________________________________________________
Master folder:
xx byte: (2 byte felt størelse, xx byte path, 8 byte dato, 8 byte subdir liste startindex, 8 byte fil liste startindex)

Subfolders:
xx byte: (1 byte felt størelse, xx byte name, 8 byte dato, 8 byte masterdir index, 8 byte subdir liste startindex, 8 byte fil liste startindex)

Files:
xx byte: (1 byte felt størelse, xx byte name, 8 byte dato, 8 byte masterdir index, 8 byte fil liste startindex)

____________________________________________________________________________

Jeg har valgt at sige at Masterfolder udgør den folder der er entrypoint til det du vil indekserer, fx "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild"
Dette har jeg i det statiske eksempel givet god plads til (1000 tegn med UTF8), dato angives med 8 byte i form af en long, samme med de 2 pointere.

En pointer er en referance til et andet sted i filen, fx er 8 byte fil liste startindex en pointer til der i filen hvor denne mappes filliste begynder.

Ang. Subfolders, så er der tale om mapper i Master dier, eller i en subfolder, der er ikke afsat så meget plads til dem da det fuldkomne path kan opbygges ud fra Master folder. det samme går for filerne.
Ved det dynamiske eksempel er der 2 byte til at angive hvor meget masterdir informationen fylder, 1 byte til subfolders og filer...

denne struktur er naturligvis antaget ud fra at man ikke har paths i hele sin computer der i (A) er længere end 1000 tegn, og i (B) ca 65000 tegn... øhhh ja...
Ved mapperne er det ved (A) ca. 100 tegn for et mappe/filnavn og (B) ca. 250 tegn...

Dette kan man jo bare ændre på... vælger man (B) kan man bruge 2 til størelsesangivelse, og hvis man har filder der har længere navne end 65000 tegn burde man vist overveje om det er smart frem for at overveje at bruge flere byte til størelses angivelse...
Avatar billede md_craig Nybegynder
27. maj 2006 - 00:42 #14
Man i princippet skrotte "8 byte subdir liste startindex" når man angiver Masterfolder Dir indexet, da de angiveligt jo kommer lige efter info om den er slut... giver 8 byte mere til text i (A)... og (B) sparer bare 8 byte
Avatar billede mcnovy Nybegynder
27. maj 2006 - 00:47 #15
det lyder som om at løsning db bliver mere og mere tiltallende..! :)
og bare rolig.. mine filnavne er ikke 65000 tegn.. max en 30 tegn eller ligende.!

jeg tror jeg vil prøve mig lidt frem.. og evt kigge lidt på din idé..!

giv svar..!
så du kan få point..
så må jeg lige vende tilbage hvis jeg får problemer med noget af det.!
Avatar billede md_craig Nybegynder
27. maj 2006 - 00:53 #16
Jow da... hehe... hvorfor skulle db være mere tiltallende? Det er sjowt at arbejde med filer på byte niveau (og bit niveau, men læsning/skrivning kan ikke gøres mindre end en byte af gangen ^^)...

Ved ikke hvor vidt du vinder noget ved DB, det er jo allerede en slags DB strikket præsist til et formål, og skulle give en ok ydelse og i dette tilfælde et minimalt ramforbrug, sagen er dog at du altid som det ser ud PT vil skulle starte med rod mappen, det kan naturligvis laves om sådan at du også kan starte på en tilfældig folder... og det kan indekseres og jeg skal komme efter dig...

(Det er ting som det her jeg elsker at arbejde med :P)
Avatar billede md_craig Nybegynder
27. maj 2006 - 00:53 #17
mehh... flot... (jeg er dog ikke så god til det der med Eksperten.dk :P)
Avatar billede mcnovy Nybegynder
27. maj 2006 - 01:16 #18
craig-.

hvis det er det her du er haj til.. så skal jeg da lige fange dig igen..!

ville være ok at lære så meget som muligt.. specielt hvis det kan gavne mig i mit projekt!
Avatar billede md_craig Nybegynder
27. maj 2006 - 01:21 #19
Hehe....

Haj og Haj... måske så meget sagt... men det er sådan noget her der interessere mig meget... så har da nogle ideer mm...

Men det bliver ikke i aften du fanger mig (for er på vej i seng :P)...

Men tror da fortsat jeg får mails på tråden selv om den er besvaret ^^...
Ellers kan jeg da godt love at kigge forbi "from time to time"... så længe jeg hænger fast i mit eget har jeg alligevel ikke meget andet at lave... (Eller dvs. øhhh.... andet som samtidigt er spændende :P)
Avatar billede md_craig Nybegynder
27. maj 2006 - 09:32 #20
ok, jeg har nok været lidt træt i går, for der er nogle ting som bliver lidt besværlige ud fra det jeg lige har lagt op til af struktur... (Kan godt lade sig gøre, men er evt. uhensigtsmessige)

Med de 2 eksempler vil filen skulle "reworkes" hver gang "stører" ændringer finder sted... og desuden er det svært at identificere "slutningen" af en "folderliste", det kan dog gøres.

Men for at gøre bestemmelsen af hvornår en folder og fil liste stopper, uden at skulle holde andres referance index, så kan man tilføje en byte til subfolders og filefolders der indikere hvor vidt der er flere folders eller ej... således:

Statisk eks: (A)
____________________________________________________________________________
Master folder:
1024 byte: (1000 byte path, 8 byte dato, 8 byte subdir liste startindex, 8 byte fil liste startindex)

Subfolders:
128 byte: (95 byte name, 8 byte dato, 8 byte masterdir index, 8 byte subdir liste startindex, 8 byte fil liste startindex, 1 byte next is part of list)

Files:
128 byte: (103 byte name, 8 byte dato, 8 byte masterdir index, 8 byte fil liste startindex, 1 byte next is part of list)



Dynamisk eks: (B)
____________________________________________________________________________
Master folder:
xx byte: (2 byte felt størelse, xx byte path, 8 byte dato, 8 byte subdir liste startindex, 8 byte fil liste startindex)

Subfolders:
xx byte: (1 byte felt størelse, xx byte name, 8 byte dato, 8 byte masterdir index, 8 byte subdir liste startindex, 8 byte fil liste startindex, 1 byte next is part of list)

Files:
xx byte: (1 byte felt størelse, xx byte name, 8 byte dato, 8 byte masterdir index, 1 byte next is part of list)

____________________________________________________________________________

den sideste byge kan så antage 2 værdier, 0 og 255 (altså faktisk en boolean)...
Antager den fx værdien 255 indikere det at det næste informationsfelt er en del af denne liste, og ellers ikke... og kan gøres omvendt ofc.

Igen falder vi så tilbage på at når filer tilføjes eller slettets, skal hele filen "genopbygges" efter ændringerne er registrerede ofc. Dette kan være helt fint hvis de oftest hændende ændringer er ændringer inde i filer. for man skal aldrig undervurdere end "ordnet liste"...

Men, hvis tilføjelse og slætninge af filer også hænder ofte vil jeg måske ligge op til en lidt anden struktur, men stadig en nærliggende en.

Statisk eks: (A)
____________________________________________________________________________
Master folder:
1024 byte: (1000 byte path, 8 byte dato, 8 byte subdir liste startindex, 8 byte fil liste startindex)

FreeSpace Index Table:
1024 byte (2 byte felt størelse, hver byte indikere startindex for en "fri blok", dette felt er "indledende/minimum" 1024 byte, men vil ændre størelse efter behov)

Subfolders:
128 byte: (80 byte name, 8 byte dato, 8 byte masterdir index, 8 byte subdir liste startindex, 8 byte fil liste startindex, 8 byte next listitem index, 8 byte last listitem index)

Padding:
Passende mængde padding til når nye folders tilføjet, hensigt er at bevare adskillelsen af filer og mapper. da en mappe eksvis fylder 128 byte kan 8192 bytes padding indeholde 64 nye mapper i det tilfælde at ingen mapper slættes...

Files:
128 byte: (96 byte name, 8 byte dato, 8 byte masterdir index, 8 byte next listitem index, 8 byte last listitem index)



Dynamisk eks: (B)
____________________________________________________________________________
Master folder:
xx byte: (2 byte felt størelse, xx byte path, 8 byte dato, 8 byte subdir liste startindex, 8 byte fil liste startindex)

FreeSpace Index Table:
1024 byte (2 byte felt størelse, hver byte par indikere startindex og slutindex for en "fri blok", dette felt er "indledende/minimum" 1024 byte, men vil ændre størelse efter behov)

Subfolders:
xx byte: (1 byte felt størelse, xx byte name, 8 byte dato, 8 byte masterdir index, 8 byte subdir liste startindex, 8 byte fil liste startindex,  8 byte next listitem index, 8 byte last listitem index)

Padding:
Passende mængde padding til når nye folders tilføjet, hensigt er at bevare adskillelsen af filer og mapper.

Files:
xx byte: (1 byte felt størelse, xx byte name, 8 byte dato, 8 byte masterdir index, 8 byte next listitem index, 8 byte last listitem index)

____________________________________________________________________________

Ok, det gjorde tingene lidt mere dynamiske når ændringer skal tilføjes...
Fx ved tilføjelse af en mappe tilføjes infomationerne på denne hvor der er plads i mappe blokken. fx der hvor der er padded plads ud, eller hvis en mappe er slettet på et tidspunk så kan den optage den plads.
I den liste den så kommer til at tilhører finder man den sidste mappe og ændre dens next index fra 0 til der hvor den nye mappe er lagret... det samme gør sig gældende med en fil der tilføjes.

Sletter man derimod en mappe, så overskrives den blok med disse info med 0 bits og tilføjer den til FreeSpace Index Table, så kan man i fremtiden finde denne frie blok og overskrive den.
FreeSpace index table kommer naturligvis til at refererer til padding blokken også.

Den del af "FreeSpace Index Table" som ikke bruges er også 0 bits (ligsom tomme felter), og det er padding også da padding er det samme som tomme felter, men bare ikke opstået fordi der er slettet noget, men er plads man har givet fra starten.
Nu kan det godt være det kom til at virke en kende mere advanceret, men spørg endelig :P
Avatar billede md_craig Nybegynder
27. maj 2006 - 09:37 #21
Med det sidste eks. vil ens fil og mappe struktur kunne gennemgå en del ændringer før at ens "Database" skal reworkes, et rework sker når:

- (1) Man løber tør for fri plads til mapper
- (2) Man løber tør for plads til at angive frie spots

Typisk vil 1 øge filens størelse, mens 2 vil reducere den.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester