[Delphi7] Bestandsgrootte bepalen zonder openen

Pagina: 1
Acties:

  • BezurK
  • Registratie: Juni 2001
  • Laatst online: 05-03 19:51
Ik ben met een applicatie bezig die met intervallen (mbv een timer) de grootte van een bestand controleerd. Dit is om na te gaan of een bepaalde applicatie nog actief is (het te controleren bestand is een logfile). Het probleem is echter dat het programma het bestand opent met exclusieve rechten en ik dus niet in staat ben om het bestand te openen alvorens ik de filesize gebruik.

Is er een mogelijkheid om de filesize te bepalen ZONDER het betreffende bestand te openen? Het moet mijns inziens mogelijk zijn want windows zèlf kan dit ook onafhankelijk van het al-dan-niet open/in gebruik zijn van een bestand

Rookworst zonder R is ook worst.


Verwijderd

hmm ff uit het hoofd

1e optie
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function MyFileSize(filename : string) : longint;
var
  fStream : TFileStream;
begin 
 try
   try
      fStream := TFileStream.Create(filename, fmOpenRead + fmShareDenyNone );
      Result := fstream.Size; 
   except
      Result := -1;
   end;
 finally
   fStream.free;
 end;
end; {}



2e optie
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function MyFileSize(filename : string) : longint;  //filename moet volledige path + filename zijn!
var
  MySR: TSearchRec;
begin
 try
   try
     if FindFirst(filename, faAnyfile, MySR) = 0 then
        Result := MySr.Size
     else
        Result := -1;
   except
     Result := -1;
   end;
 finally
   findclose(MySr);
 end;
end;


Optie 2 kan nogal wat performance impact hebben op een netwerk omgeving.


En er is ook een of andere windows api call natuurlijk.

[ Voor 68% gewijzigd door Verwijderd op 16-03-2004 21:48 ]


Verwijderd

BezurK schreef op 16 maart 2004 @ 20:43:
Dit is om na te gaan of een bepaalde applicatie nog actief is (het te controleren bestand is een logfile
Kun je niet kijken of het process nog leeft?

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 15-05 14:44

_Thanatos_

Ja, en kaal

Bovenste methode van maui71 opent het bestand nog steeds. Onderste methode ziet er wat rommelig uit, maar dat is wel de enige goeie methode. Een goeie test is om de grootte van je pagefile proberen op te vragen. Dat lukt alleen met de onderste methode. Onderste methode heeft geen overmatige impact op performance, omdat Windows deze methode intern ook gebruikt als alleen de grootte van een bestand opgevraagd moet worden.

En ja, er is ook een API call, GetFileSize[Ex], maar die moet je een handle geven en dus moet het bestand ook weer geopend worden ;)

[ Voor 19% gewijzigd door _Thanatos_ op 16-03-2004 21:44 ]

日本!🎌


Verwijderd

_Thanatos_ schreef op 16 maart 2004 @ 21:44:
Bovenste methode van maui71 opent het bestand nog steeds. Onderste methode ziet er wat rommelig uit, maar dat is wel de enige goeie methode.
Heb 'm een beetje beter uitgelijnd :)
Een goeie test is om de grootte van je pagefile proberen op te vragen. Dat lukt alleen met de onderste methode. Onderste methode heeft geen overmatige impact op performance, omdat Windows deze methode intern ook gebruikt als alleen de grootte van een bestand opgevraagd moet worden.
Wel als je zoals bv. TS wilt met een bepaalde interval (bv. iedere seconde), de grootte opvraagt.
En ja, er is ook een API call, GetFileSize[Ex], maar die moet je een handle geven en dus moet het bestand ook weer geopend worden ;)
Aan die zat ik ook te denken, maar moet idd een geopende handle hebben.

[ Voor 4% gewijzigd door Verwijderd op 16-03-2004 21:51 ]


  • BezurK
  • Registratie: Juni 2001
  • Laatst online: 05-03 19:51
Verwijderd schreef op 16 maart 2004 @ 21:09:
[...]


Kun je niet kijken of het process nog leeft?
Ja, dat kan, maar het process leeft altijd. Het betreft namelijk een callcenter. Die logt alle inkomende gesprekken in een logfile. De opdrachtgever (nee, het is niet voor mezelf, voor een kennis) heeft die software in gebruik maar moet nu zelf zo'n beetje ieder uur in de logfile kijken of er wel activiteit geweest is in het laatste uur.
Hij wil graag een programma wat dus met een interval van bijvoorbeeld 30 minuten de filesize checked, en als de filesize in die interval gelijk is gebleven dan moet het programma een mailtje sturen naar een vooraf gegeven mail-adres. Ik heb alles al werkend, maar ik kwam erachter dat het dus niet werkte op al geopende bestanden...
Verwijderd schreef op 16 maart 2004 @ 21:48:
[...]

Wel als je zoals bv. TS wilt met een bepaalde interval (bv. iedere seconde), de grootte opvraagt.

Aan die zat ik ook te denken, maar moet idd een geopende handle hebben.
Performance is geen issue. De interval zal nooit minder zijn dan minuten, waarschijnlijk zelfs niet minder dan een uur.

Ik ga morgen jouw methode uitproberen, ik hoop dat het werkt! Thx bij voorbaat! _/-\o_ (richting jullie alle 3 btw ;))

Rookworst zonder R is ook worst.


Verwijderd

BezurK schreef op 16 maart 2004 @ 23:04:
[...]

Ja, dat kan, maar het process leeft altijd. Het betreft namelijk een callcenter. Die logt alle inkomende gesprekken in een logfile. De opdrachtgever (nee, het is niet voor mezelf, voor een kennis) heeft die software in gebruik maar moet nu zelf zo'n beetje ieder uur in de logfile kijken of er wel activiteit geweest is in het laatste uur.
Hij wil graag een programma wat dus met een interval van bijvoorbeeld 30 minuten de filesize checked, en als de filesize in die interval gelijk is gebleven dan moet het programma een mailtje sturen naar een vooraf gegeven mail-adres. Ik heb alles al werkend, maar ik kwam erachter dat het dus niet werkte op al geopende bestanden...
Is het niet mogelijk om dit in het pakket te implimenteren? Rised deze geen event hiervoor? Ik weet niet welk pakket hij gebruikt.

edit:

Heeft Delphi niet zoiets als een FileWatcher ofzo?

[ Voor 5% gewijzigd door Verwijderd op 16-03-2004 23:21 ]


Verwijderd

Verwijderd schreef op 16 maart 2004 @ 23:21:
[...]


Is het niet mogelijk om dit in het pakket te implimenteren? Rised deze geen event hiervoor? Ik weet niet welk pakket hij gebruikt.

edit:
Heeft Delphi niet zoiets als een FileWatcher ofzo?
Ja, je kan idd ook een filechangednotify (weet ff de preciese naam niet), gebruiken (onder NT systemen dus NT/2000/XP). Echter deze vuurt nogal vaak af als je wegschrijft naar een file, en zeker bij het aanmaken ervan. Als TS interesse in deze api heeft, kan ik morgen wel ff een stukje code posten hiervoor.

Verwijderd

Verwijderd schreef op 16 maart 2004 @ 23:28:
[...]

Ja, je kan idd ook een filechangednotify (weet ff de preciese naam niet), gebruiken (onder NT systemen dus NT/2000/XP). Echter deze vuurt nogal vaak af als je wegschrijft naar een file, en zeker bij het aanmaken ervan. Als TS interesse in deze api heeft, kan ik morgen wel ff een stukje code posten hiervoor.
Hij controleerd eens per 30 min... dus dat zit wel snor.. :9

Verwijderd

Verwijderd schreef op 16 maart 2004 @ 23:34:
[...]


Hij controleerd eens per 30 min... dus dat zit wel snor.. :9
Niet de api die ik bedoel, die wordt ongeveer afgevuurd zodra een file wordt aangemaakt/gewijzigd/verwijderd/verplaatst

[ Voor 20% gewijzigd door Verwijderd op 17-03-2004 00:01 ]


Verwijderd

Verwijderd schreef op 17 maart 2004 @ 00:00:
[...]

Niet de api die ik bedoel, die wordt ongeveer afgevuurd zodra een file wordt aangemaakt/gewijzigd/verwijderd/verplaatst
TurboPower ShellShock

Pseudo code:
code:
1
2
3
4
if (LastEvent < (Now-30) then
begin
  ShowMessage('Ok. Er is een wijziging');
end;

Verwijderd

Verwijderd schreef op 16 maart 2004 @ 23:28:
[...]

Ja, je kan idd ook een filechangednotify (weet ff de preciese naam niet), gebruiken (onder NT systemen dus NT/2000/XP). Echter deze vuurt nogal vaak af als je wegschrijft naar een file, en zeker bij het aanmaken ervan. Als TS interesse in deze api heeft, kan ik morgen wel ff een stukje code posten hiervoor.
Op een beetje goede filewatcher kun je het fire'n van de events stoppen en starten.

  • schoene
  • Registratie: Maart 2003
  • Laatst online: 15:39
als je enkel wil weten of het programma nog actief is, is controleren of de logfile nog gewijzigd wordt geen goeie oplossing vind ik. Wat beter is, is naar het bestaande programma een bericht te sturen, en kijken of je een antwoord krijgt. Dit kan met de WinApi SendMessageTimeout

Verwijderd

schoene schreef op 17 maart 2004 @ 08:52:
als je enkel wil weten of het programma nog actief is, is controleren of de logfile nog gewijzigd wordt geen goeie oplossing vind ik. Wat beter is, is naar het bestaande programma een bericht te sturen, en kijken of je een antwoord krijgt. Dit kan met de WinApi SendMessageTimeout
Het gaat volgens mij alleen om deze log... SendMessage is geen oplossing voor hem. Want het process draait in prenciepe altijd, zoals Bezurk al aan gaf.

  • schoene
  • Registratie: Maart 2003
  • Laatst online: 15:39
In zijn openingspost schrijft hij dit:
Ik ben met een applicatie bezig die met intervallen (mbv een timer) de grootte van een bestand controleerd. Dit is om na te gaan of een bepaalde applicatie nog actief is (het te controleren bestand is een logfile)
Ik vermoed dat hij eigenlijk wil weten of het proces nog reageert of niet. En dit kan je te weten komen via sendmessagetimeout. Indien mijn vermoeden verkeerd is, dan is mijn oplossing idd mss niet juist.

  • Reptile209
  • Registratie: Juni 2001
  • Laatst online: 23:53

Reptile209

- gers -

schoene schreef op 17 maart 2004 @ 09:59:
In zijn openingspost schrijft hij dit:

[...]


Ik vermoed dat hij eigenlijk wil weten of het proces nog reageert of niet. En dit kan je te weten komen via sendmessagetimeout. Indien mijn vermoeden verkeerd is, dan is mijn oplossing idd mss niet juist.
BezurK schreef op 16 maart 2004 @ 23:04:
[...]

Ja, dat kan, maar het process leeft altijd. Het betreft namelijk een callcenter. Die logt alle inkomende gesprekken in een logfile. [...] De opdrachtgever [...] moet nu zelf zo'n beetje ieder uur in de logfile kijken of er wel activiteit geweest is in het laatste uur.
Hij wil graag een programma wat dus met een interval van bijvoorbeeld 30 minuten de filesize checked, en als de filesize in die interval gelijk is gebleven dan moet het programma een mailtje sturen naar een vooraf gegeven mail-adres.
De TS wil dus niet weten of het proces nog leeft, maar of het proces nog wat te doen heeft. In wat begrijpelijkere taal (gokje op callcenter ervaring) wil de TS het volgende:
• Er is een callcenter met een logprogramma (dat gesprekken monitort ofzo)
• Tijdens een gesprek groeit de logfile
• Als er geen gesprekken zijn (bijv. geen calls, storing of na sluitingstijd), groeit de logfile niet
• Als er lange tijd geen gesprekken zijn, is er misschien iets mis en moet men actie ondernemen -> verzend een email naar paniek@callcenter.nl.
• De enige manier om daar via de software achter te komen, is dus het monitoren van de logfile.

Dus nou kappen met "leeft het proces nog"-oplossingen :).
Verwijderd schreef op 16 maart 2004 @ 23:34:
[...]
Hij controleerdt eens per 30 min... dus dat zit wel snor.. :9
Toch moet je er voor oppassen, dat je niet 100 events krijgt voordat je de eerste afgehandeld hebt. Dat is moordend voor je performance. De eerste stap in die event-handler moet dan ook zijn om ofwel de events tijdelijk te stoppen, ofwel te constateren dat er al een event wordt afgehandeld en meteen "klaar" zijn.

Zo scherp als een voetbal!


  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 21-05 14:59

pjvandesande

GC.Collect(head);

Reptile209 schreef op 17 maart 2004 @ 10:11:
Toch moet je er voor oppassen, dat je niet 100 events krijgt voordat je de eerste afgehandeld hebt. Dat is moordend voor je performance. De eerste stap in die event-handler moet dan ook zijn om ofwel de events tijdelijk te stoppen, ofwel te constateren dat er al een event wordt afgehandeld en meteen "klaar" zijn.
Je kan toch aangeven of de event getricherd worden of niet?

  • Reptile209
  • Registratie: Juni 2001
  • Laatst online: 23:53

Reptile209

- gers -

questa schreef op 17 maart 2004 @ 10:18:
[...]


Je kan toch aangeven of de event getricherd worden of niet?
Maar dat moet je dan dus ook wel doen :). Ik las de reactie van de TS als: de belasting door zo'n event is laag, want ik wil maar eens per 30 min weten hoe het er voor staat. Terwijl zo'n event zich daar niks van aantrekt als je hem aan laat staan: die wordt gewoon getriggerd als er wat met je file gebeurt.
Kortom: eeste event komt, events stoppen, event afhandelen, events starten (evt na een korte pauze om te voorkomen dat je nogmaals dezelfde schrijfactie voor je plaat krijgt).

Zo scherp als een voetbal!


Verwijderd

TS kan ook hier even rondkijken: http://www.torry.net/pages.php?id=252

Ik heb een eigen component gemaakt, hiervoor, met allerlei extra opties. Echter deze werkt op basis van findfirst/findnext (dus inlezen directory structuur), niet op de ReadDirectoryChangesW api, die vond ik persoonlijk niet lekker werken (bovendien alleen NT gebaseerde systemen). Je kan ook nog gebruik maken van 'FindFirstChangeNotification' en gerelateerde apicalls, echter deze schijnen nogal eens een en ander te missen qua file events.

[ Voor 4% gewijzigd door Verwijderd op 17-03-2004 10:59 ]


  • Dala
  • Registratie: November 2000
  • Laatst online: 26-05 23:47
nog een ander file size

Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
Function FileSizeInBytes(FileName : String) : LongInt;
var
   f: file of Byte;
begin
 AssignFile(f, FileName);
 Reset(f);
 try
   Result := FileSize(f);
 finally
   CloseFile(f);
 end;
end;

  • Reptile209
  • Registratie: Juni 2001
  • Laatst online: 23:53

Reptile209

- gers -

Dala schreef op 17 maart 2004 @ 11:24:
nog een ander file size

Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
Function FileSizeInBytes(FileName : String) : LongInt;
var
   f: file of Byte;
begin
 AssignFile(f, FileName);
 Reset(f);
 try
   Result := FileSize(f);
 finally
   CloseFile(f);
 end;
end;
Leuke poging, maar probeer dat maar eens op je swapfile uit: werkt voor geen meter. Die software (of windows bij de swapfile) heeft exclusieve lees/schrijf rechten, waardoor je assign volledig de mist in gaat. Dit doet het dus niet in deze situatie. :)

Zo scherp als een voetbal!


  • BezurK
  • Registratie: Juni 2001
  • Laatst online: 05-03 19:51
Reptile209 schreef op 17 maart 2004 @ 10:11:
De TS wil dus niet weten of het proces nog leeft, maar of het proces nog wat te doen heeft. In wat begrijpelijkere taal (gokje op callcenter ervaring) wil de TS het volgende:
• Er is een callcenter met een logprogramma (dat gesprekken monitort ofzo)
• Tijdens een gesprek groeit de logfile
• Als er geen gesprekken zijn (bijv. geen calls, storing of na sluitingstijd), groeit de logfile niet
• Als er lange tijd geen gesprekken zijn, is er misschien iets mis en moet men actie ondernemen -> verzend een email naar paniek@callcenter.nl.
• De enige manier om daar via de software achter te komen, is dus het monitoren van de logfile.
Jij snapt'm helemaal :)

Daarnaast heb ik geen toegang tot het programma, laat staan de sourcecode! Een functie erin bouwen is dus compleet onmogelijk. Sterker nog, de server waar mijn app op moet komen te draaien heb ik nog nooit van m'n leven gezien :P

Mijn opdrachtgever ('t is meer een soort van vriendendienst, maargoed) is namelijk netwerkbeheerder en één van z'n klanten (remote-beheer klant) heeft dus dit probleem. Hij had een oplossing ervoor bedacht in de vorm van het checken van de logfile. Hij is niet gek dus ik ga ervan uit dat zijn oplossing de beste oplossing is. Hij heeft alleen geen programmeerervaring dus het viel totaal buiten zijn kunnen om er iets voor te maken...
Ik mag toch hopen dat het nu duidelijk is wat ik wil :+

maar evengoed wel tof dat jullie meedenken hoor ;)

Ik heb de 2e oplossing van maui71 geprobeert en die werkt vlekkeloos :*)
Verwijderd schreef op 17 maart 2004 @ 10:58:
TS kan ook hier even rondkijken: http://www.torry.net/pages.php?id=252

Ik heb een eigen component gemaakt, hiervoor, met allerlei extra opties. Echter deze werkt op basis van findfirst/findnext (dus inlezen directory structuur), niet op de ReadDirectoryChangesW api, die vond ik persoonlijk niet lekker werken (bovendien alleen NT gebaseerde systemen). Je kan ook nog gebruik maken van 'FindFirstChangeNotification' en gerelateerde apicalls, echter deze schijnen nogal eens een en ander te missen qua file events.
* BezurK bookmarked... handige site! _/-\o_

[ Voor 18% gewijzigd door BezurK op 17-03-2004 13:51 ]

Rookworst zonder R is ook worst.


  • Monga
  • Registratie: Mei 2002
  • Laatst online: 22:02
BezurK schreef op 17 maart 2004 @ 13:46:
[...]
Ik heb de 2e oplossing van maui71 geprobeert en die werkt vlekkeloos :*)
Zo ver ik weet moet je de FindClose alleen doen als de FindFirst is gelukt; als er namelijk geen bestand wordt gevonden heb je geen handle in je TSearchRec en gaat FindClose een beetje zeuren ;)

Dus wordt het
code:
1
2
3
4
5
6
7
8
9
10
11
12
function MyFileSize(filename : string) : longint;  //filename moet volledige path + filename zijn!
var
  MySR: TSearchRec;
begin
  if FindFirst(filename, faAnyfile, MySR) = 0 then
  begin
    Result := MySr.Size;
    FindClose(MySR);
  end
  else
    Result := -1;
end;

  • Antonius
  • Registratie: Juli 2000
  • Laatst online: 21-05 21:10
Mogelijk komt de timestamp van het logbestand ook nog van pas. Is een betrouwbaarder manier om te zien of er in het laatste uur nog iets aan die file is veranderd dan alleen de size.

code:
1
2
3
4
5
6
7
8
var
  MySR: TSearchRec;
  dtModified: TDateTime;
begin
  ...
  dtModified := FileDateToDateTime(MySR.Time);
  ...
end;


"TSearchRec.Time contains the time stamp of the file. It can be converted to a TDateTime value using FileDateToDateTime."

[ Voor 3% gewijzigd door Antonius op 17-03-2004 22:07 ]

Pagina: 1