Results 1 to 15 of 15

Thread: gebruik Tfilestream

  1. #1

    gebruik Tfilestream

    beste specialisten
    Uit een extern programma krijg ik real time data(zeer onregelmatig en steeds 1 regeltje welke steeds ververst wordt: xxxx;yyyy; ) in een kladblok (prn-file)aangeleverd.
    Dit extern programma(een scripttaal ,met weinig meer mogelijkheden dan deletefile en appendfile) moet de gegevens wel kwijt kunnen anders geeft het daar een exception en stokt de toevoer van gegevens.
    Dat is helaas een gegeven ;daar kan ik niets aan veranderen.
    Nu wil ik die data uit de prn-file lezen en in een eigen programma verwerken.
    Tot nu toe heb ik gegevens beperkt tot een enkel getal welk via een timer elke seconde uitlees.via een stringlistcreate\load \savefile constructie
    Maar wanneer veel data aangeleverd worden , dan komt het voor dat het aanleverende progrmma in de fout gaat.
    Ik wilde daarom tfilestream gebruiken omdat het daar mogelijk is via een buffer een file gelezen kan worden terwijl een een extern programma wel in deze file kan schrijven .Toch gaat nog steeds het aanleverde programma in de fout.

    ik doe dit nu als volgt
    Code:
     function Tophaler.ReadStringFromFile(AFileName: string): string;
     var
       FileStream: TFileStream;
       Size: Integer;
     begin
       Result := '';
       if not FileExists(AFileName) then
         Exit;
       FileStream := TFileStream.Create(AFileName, fmShareDenyread);
       Size := FileStream.Size;
       if Size > 0 then
       begin
         SetLength(Result, Size);
         FileStream.ReadBuffer(Result[1], Size);
       end;
       FreeAndNil(FileStream);
     end;
    de funktie is opgenomen in de procedure streamdataophaler welke wordt angeroepen in een timer met interval va 1 sec:
    Code:
    procedure Tophaler.streamdataophaler;
    var  totaalstring :ansistring;
         datAstring,datBstring:ansistring;
         SL: TStringList;
    begin
         totaalstring:= ReadStringFromFile(  datafileregel);
    
         SL := TStringList.Create;
       try
         SL.Delimiter := ';';
         SL.StrictDelimiter := True;
         SL.DelimitedText := totaalstring;
         datAstring := SL.Strings[0];
         datBstring:=SL.Strings[1];
          fgegevenA:=strtofloat(datAstring);
          FgegevenB:= strtoint( datBstring);
    
       finally
         SL.Free;
       end;
    
       .
       .
       .
       .etc
    end;
    wat gaat hier fout
    Last edited by freddie2; 15-Jul-13 at 14:38.

  2. #2
    Wat gaat er mis? Krijg je een foutmelding? Hoe opent de andere partij het bestand?

    Let op dat de andere partij echt alleen maar mag schrijven en dus niet mag lezen.
    Marcel

  3. #3
    marcel,

    de foutmelding vindt niet in lazarus, maar in het scriptprogramma plaats, waarin aangegeven wordt dat de file("file delete failed') niet gevonden wordt.
    Lazarus blokkeert op de een of andere manier toch het verversen van de file.(zonder de datatap via lazarus heeft de datalevering probleemloos gedraaid)
    het gaat ook best een tijdje goed ;alleen wanneer veel data geleverd worden dan gebeurt het.

    in dat script-programma kun je alleen deletefile(afilenaam) en appendfile(afilenaam,teladenstring) opgeven.

    dus om maar 1 regel op te geven wordt dus eerst de delete (en hiermede wordt de file geopend) geven en daarna de append .

    opmerking: ik heb nog een edit van mijn bericht doorgevoerd waarin melding wordt gemaakt van het gebruik van een timer.
    oorspronkelijk dacht ik zonder die timer te kunnen werken want ik had begrepen dat filestream, bij wijzigingen in de datafile ,zelf de buffer zou vullen


    het lijkt erop dat je een kunstmatige timesharing moet gaan optuigen vooral ook omdat ik de data als input voor grafieken en een vrij zwaar programma wil gaan gebruiken.
    Last edited by freddie2; 15-Jul-13 at 15:46.

  4. #4
    Ik denk niet dat je een delete kunt doen op een bestand dat je met fmShareDenyread hebt geopend. Maar je protocol is eerlijk gezegd wat foutgevoelig, kun je niet op een andere manier communiceren?
    Marcel

  5. #5
    nee, momenteel zijn er geen andere mogelijkheden. het is inderdaad foutgevoelig

    het leek erop dat fmShareDenynone beter ging ,maar daar heb ik ook foutmelding ontvangen.

    maar terugkomend op het gebruik van een timer. daar blijf ik mijn twijfels houden.
    kan dat nou niet anders .want als de inhoud van de file veranderd dan is dat het signaal en het zijn tenslotte maar 1kb file-tjes .

  6. #6
    Jazeker, je kunt shell notifications op een map zetten waardoor je een event krijgt zodra er iets wijzigt in een map. Dat is inderdaad efficiënter dan een timer, je doet immers alleen maar iets als er iets verandert.

    JVCL / JCL heeft hiervoor kant en klare componenten.
    Marcel

  7. #7
    ik ga eens op zoek, alvast bedankt
    ik zie voorlopig dat alleen voor delphi is en niet voor lazarus maar ik zal het wel mis hebben
    kun je iets specifieker worden
    Last edited by freddie2; 15-Jul-13 at 18:31.

  8. #8
    bedoel je zoiets als het navolgende?
    ik werk momenteel in vista
    Code:
    Function FileLastModified
       (const TheFile: string): string;
    var
      FileH : THandle;
      LocalFT : TFileTime;
      DosFT : DWORD;
      LastAccessedTime : TDateTime;
      FindData : TWin32FindData;
    begin
      Result := '';
      FileH := FindFirstFile(PChar(TheFile), FindData) ;
      if FileH <> INVALID_HANDLE_VALUE then begin
       Windows.FindClose(Handle) ;
       if (FindData.dwFileAttributes AND
           FILE_ATTRIBUTE_DIRECTORY) = 0 then
        begin
         FileTimeToLocalFileTime
          (FindData.ftLastWriteTime,LocalFT) ;
         FileTimeToDosDateTime
          (LocalFT,LongRec(DosFT).Hi,LongRec(DosFT).Lo) ;
         LastAccessedTime := FileDateToDateTime(DosFT) ;
         Result := DateTimeToStr(LastAccessedTime) ;
        end;
      end;
    end;

  9. #9
    Nou, ik bedoelde eigenlijk meer:

    delphi Code:
    1. object JvChangeNotify1: TJvChangeNotify
    2.   Active = True
    3.   Notifications = <
    4.     item
    5.       Directory = 'c:\temp'
    6.     end>
    7.   OnChangeNotify = JvChangeNotify1ChangeNotify
    8.   Left = 384
    9.   Top = 152
    10. end

    delphi Code:
    1. procedure TForm7.JvChangeNotify1ChangeNotify(Sender: TObject; Dir: string;
    2.     Actions: TJvChangeActions);
    3. begin
    4.   Memo1.Lines.Add('Change');
    5. end;

    Op deze manier krijg je een event als er iets wijzigt in de map c:\temp. Je kunt ook nog instellen van welke wijzigingen je een event wilt krijgen. In dat event kun je vervolgens kijken of jouw bestand is gewijzigd en daar dan op reageren.
    Marcel

  10. #10
    oke, maar dat is een jedi vcl component

    .waar kan ik die voor lazarus vinden .ik krijg zoals genoemd alleen maar verwijzingen naar delphi(niet onlogisch voor de jedi groeP)

  11. #11
    Ai, sorry.. dat had ik gemist. Ik ga er te makkelijk vanuit dat de "standaard" libraries ook Lazarus broertjes hebben, dat is niet terecht natuurlijk.

    Delphi about heeft een Monitoring System Shell Changes using Delphi, maar ik weet niet of dat eenvoudig in Lazarus te gebruiken is. Het is sowieso natuurlijk wel een Windows specifieke oplossing.
    Marcel

  12. #12
    ja, een windows specifiek oplossing en daar wilde ik juist vanaf en heb de overstap naar lazarus gemaakt
    ik ga maar voor een harde tijdsscheiding tussen het laden en het lezen van de file .
    Dit levert wat tijdsvertraging op en de file-tjes gaan uit meerdere regels bestaan maar dat moet dan maar(script kan wel momentane waarde wel weergeven maar vreemd genoeg niet per seconde opslaan).File voor de even minuten (die dan geladenwordt)en een voor de oneven minuten(die op datzelfde moment gelezen en in het lazarus programma verwerkt wordt).Bij de volgende minuut net omgekeerd

  13. #13
    Senior Member Thaddy's Avatar
    Join Date
    Dec 2004
    Location
    Amsterdam
    Posts
    2,211
    Quote Originally Posted by freddie2 View Post
    ja, een windows specifiek oplossing
    Wat doet je denken dat je het wiel moet uitvinden? Het gaat om het algoritme.
    Onder *nix zijn er veel meer en elegantere oplossingen voor dit soort dingen.
    Eerst maar eens even je nieuwe platform api's leren dan?
    Voordat je om je gebrek aan kennis heen programmeert? (Been there, done it, payed the price, looong time ago)

    Ga je nu nog even niet helpen na deze toch wel wat wereldvreemde benadering.

    Zucht.
    Werken aan Ansi support voor Windows is verspilde tijd, behalve voor historici.

  14. #14
    Als je onderweg bent, is het belangrijker de auto rijdend te houden(en goedkoper) dan direct steeds een nieuwe willen maken.Voor mij is het programma zelf niet het doel maar slechts een middel .
    Maar er zijn meerdere wegen naar Rome en ik heb ,bij gebrek aan de route kaart en passende onderdelen, voor deze oplossing gekozen.Wanneer ik weer tijd heb voor onderhoud zullen we kijken of we betere oplossing kunnen vinden.

    Maar je hebt best een punt ,waarvan ik me ten volle van bewust ben.

    En soms heb je aan een kleine verwijzing genoeg om uit de enorme brei aan 'informatie' uiteindelijk 'kennis' op te doen.

    en .........echte ervaring is nu eenmaal gecondenseerde elllende

  15. #15
    ps deze wereldvreemde benadering blijkt veel voordeliger dan gedacht en levert me nu, in het zware grafische gedeelte dat door deze data wordt aangestuurd ,zoveel besparing aan rekenruimte op dat daar mijn analyses kunnen worden uitgebreid.
    Daarbij blijkt een inmiddels stevige verbinding met het scriptprogramma te zijn ontstaan waar we weer jaren mee vooruit kunnen.

    en zo heeft elk nadeel toch zijn voordeel.
    mijn dank voor degene die hebben meegedacht .

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •