Avatar billede muttley Nybegynder
02. april 2001 - 12:11 Der er 29 kommentarer og
1 løsning

Endnu en Delphi Newbie!

Hejsa allesammen...

Jeg har lavet et Checksum program i delphi5, som finder/retter flere checksumme i en ROMfil fra en bil..

Problemet er bare, at det tager 100 År,  da den måde jeg gør det på,  er helt forkert..

Jeg bruger nemlig :

AssignFile(bla,bla);
Reset(Bla);
Seek(Bla,bla);
CloseFile(Bla);

\"Assign´er/Reset´er selvfølgelig ikke filen hver gang jeg seek´er,  men alligevel er metoden alt for langsom..\"  Filen er på ca 1 MB.

Det jeg gerne ville,  var at ligge hele filen i hukommelsen,  og så søge der,  det ville få lortet til at gå 1000 gange hurtigere.. :)

Men jeg fatter bare helt minus når vi snakker sådan noget.. :(

Jeg ville gerne have et eksempel på hvordan man ligger en fil i hukommelsen,  og derefter kan læse EN byte af gangen..

F.eks.  :

Var
  ReadByte : Byte;
  Counter  : LongInt;

Begin 
  For A:=1 to  FileSize(RomFile) do 
    ReadByte:=File_In_Memory[Counter];
End;


PS. Undskyld hvis jeg har skrevet for meget, for at forklare så lidt..!
Avatar billede borrisholt Novice
02. april 2001 - 12:14 #1
du kan erklære dig er array of byte som du så kalder en SetLenght() på når du ved hvor meget mem du skal bruge ... Så er det bare at søge / ændere i din buffer.

Jens B
Avatar billede microtec Nybegynder
02. april 2001 - 12:14 #2
Brug BLOCKREAD i stedet for. Så kan du indlæse en stor blok data ad gangen. Behandle denne blok og så læse en stor blok igen.
Det vil speede hastighede meget op. Nu står du od læser en byte fra disken ad gangen.

Prøv at læse om BLOCKREAD i online-hjælpen.
Avatar billede martinlind Nybegynder
02. april 2001 - 12:17 #3
Prøv at kigge lidt på Stream\'s, f.eks. TMemoryStream, den er ok

MemStream.LoadFromFile();
MemStream.Memory^ , giver dig en pointer til din hukommelse, du kan også evt. sætte denne pointer til en PChar og så bare tælle denne op :

P := PChar(MemStream.Memory);
P := P + 1;

osv. Håber det hjalp

/Martin
Avatar billede microtec Nybegynder
02. april 2001 - 12:21 #4
Martin >> TMemoryStream kan fint anvendes her, men bliver det ikke unødigt kompliceret for en Newbie?
Stream´s er ikke det letteste tilgængelige ;o)
Avatar billede martinlind Nybegynder
02. april 2001 - 12:28 #5
Microtec >> BlockRead er heller ikke det nemeste med at tilpasse block\'en til fil størelse osv. der er en masse du kan holde øje med, og en memorystream castet til en pchar er nu temmelig nem at håndtere. Hvis man ikke vil bruge en stream, så er et array da nok det smarteste, som boris nævner.
Avatar billede muttley Nybegynder
02. april 2001 - 12:38 #6
Det er helt vildt så hurtigt man får svar herind!

BlockRead kan desværre ikke bruges,  da jeg har lavet programmet sådan at den seek´er i filen,  og bruger den byte den har læst..

\"Har brugt RomFile : File of Byte;\"

Men det med at ligge helt lortet i en Array er måske ikke så dårlig ide,  troede bare ikke man kunne lave så stor en Array..

Men problemet er jo bare,  at jeg ikke ved på forhånd helt hvor stor filen er..  Så jeg kan vel ikke bare sige RomArray : Array[1..RomSize] of Byte;    Kan jeg ??

PS.  Sidder ikke lige ved en maskine med Delphi lige nu :(  Troede ikke det gik så hurtigt herinde !!

Jeg vil lige undersøge det så hurtigt jeg kan, og så skrive om det virker/give point..

PS2.  Jeg fatter ikke en klap om pointer,  så hvis jeg skulle bruge det,  skal jeg desværre nok have et rimelig godt eksempel på hvordan det skulle laves..
Avatar billede microtec Nybegynder
02. april 2001 - 12:45 #7
martinlind >> Jeg mente bare at når du benytter memorystream begynder du også at snakke pointer ;o)

boris løsning med et array er fin, da man så kan læse hele arrayet i et hug. Det forudsætter bare at filen har den samme størrelse hele tiden.

Mht. Blockread, så behøver du ikke tilpasse bloken til filstørrelsen. Du kan f.eks. læse 64KByte ad gangen. Hvis den sidste læsning ikke fylder 64K, læses der blot den resterende del. Parametren \"Count\" fortæller så hvor mange bytes der blev læst.

Avatar billede microtec Nybegynder
02. april 2001 - 12:47 #8
muttley >> Dit program vil blive langsom når du seek´er i filen. Det er det der tager tid.
Du kan f.eks. læse 64K ind med Blockread. Lave checsum-beregninger på denne blok i memory, og så læse den næste blok.
Avatar billede martinlind Nybegynder
02. april 2001 - 12:47 #9
VAR

RomArry : array of byte;
F  : TMemoryStream;

begin
  F := TMemoryStream.Create;
  F.LoadFromFile(<FileName>);
  SetLength(RomArray,F.Size);
  Move(F.Memory^,RomArray,F.Size);
  SetLength(<RomArray-size>);
  F.Free;
  // Også ellers bare der udaf *S*
 
  RomArray[Index];


end;

/Martin
Avatar billede martinlind Nybegynder
02. april 2001 - 12:48 #10
den sidste SetLength skal lige fjernes. *S*
Avatar billede microtec Nybegynder
02. april 2001 - 12:51 #11
martinlind >> RomArry skal have en størrelse ;o)
Avatar billede martinlind Nybegynder
02. april 2001 - 12:51 #12
microtec >> open arrays findes i d5, og du skal lave housekeeping hvis du bruger blockread, funktionerne der laver checket skal jo kunne håndetere forskellig længde af din block, og hvad nu hvis du skal bruge en byte fra den sidste og en fra den næste osv.

/Martin
Avatar billede martinlind Nybegynder
02. april 2001 - 12:52 #13
Microtec >> LÆS din D5 hjælp *S* ( og mit eks. )
Avatar billede microtec Nybegynder
02. april 2001 - 12:53 #14
martinlind >> OK, så er det derfor jeg ikke kender tricket med \"array of byte\". Der skal angives en størrelse i andre versioner af Delphi.
Avatar billede microtec Nybegynder
02. april 2001 - 12:54 #15
martinlind >> Rolig Martin. Nu er det jo ikke alle der benytter D5, vel *gg*
Avatar billede muttley Nybegynder
02. april 2001 - 13:04 #16
Såså,  rolig nu allesammen.. :)

Jeg er vildt imponeret over den respons der er kommet,  og tror godt jeg kan komme videre med det i har skrevet indtil nu..

Men jeg skrev nu altså i mit spørgsmål at jeg havde lavet det i Delphi5..

Og til sidst,  så kan blockRead altså desværre ikke bruges,  da jeg ikke bare starter fra starten af filen,  og læser til enden,  jeg skal kunne bruge data fra rundt omkring i filen hele tiden..
Avatar billede microtec Nybegynder
02. april 2001 - 13:17 #17
muttley >> Du skal læse HELE finen ind i memory, og så hoppe rundt i memory og hente dine data. Det er langsomt hvis du hopper rindt og henter data forskellige steder i selve filen.
BlockRead kan fint bruges til dette. De andre løsninger er også gode. Martin´s og Boris´s forslag kræver bare at du benytter Delphi5. Jeg var ikke klar over at Array´s var ændret i denne version. Erklæringen \"RomArry : array of byte;\" er ikke lovlig i de versioner af Delphi jeg sidder med.


Bare rolig, Martin og jeg har haft værre diskussioner end denne. Så længe der er *s* og *gg* er det ikke så slemt :o)
Avatar billede microtec Nybegynder
02. april 2001 - 13:19 #18
PS: Velkommen til forresten. Ja, der er hurtig respons. Især her i Delphi-kategorien. Der er altid nogen der gerne vil hjælpe :o)
Avatar billede martinlind Nybegynder
02. april 2001 - 14:00 #19
microtec >> *S*
Avatar billede muttley Nybegynder
02. april 2001 - 17:03 #20
martinlind >>  Jeg gad utroligt godt at kunne bruge din metode,  og har jeg prøvet at lege lidt med det,  men har desværre ikke fået ret meget ud at det,  andet end at min computer skulle genstartes nogle gange.. :(

Jeg har forsøgt at gøre som du sagde,  men har åbenbart ikke fået det hele på plads..

Hvad gør jeg lige galt ??  :

procedure TForm1.Button1Click(Sender: TObject);

Var
  RomArray : array of byte;
  F        : TMemoryStream;

begin
  If OpenDialog1.Execute then
    Begin
      Edit1.Text:=\'Loading..\';
      F := TMemoryStream.Create;
      F.LoadFromFile(OpenDialog1.FileName);
      SetLength(RomArray,F.Size);
      Move(F.Memory^,RomArray,F.Size);
      Edit1.Text:=\'File loaded\';
    End;
end;

PS.  Computer går under eller kommer med en fejlmeddelse,  efter jeg har valgt en fil i OpenDialog boxen.. :(
Avatar billede muttley Nybegynder
02. april 2001 - 19:45 #21
Glemte lige noget..

Det er linjen her :

Move(F.Memory^,RomArray,F.Size);

Den ikke er så glad for..  Fjerner jeg den,  er der ikke noget der går i kage..
Avatar billede martinlind Nybegynder
03. april 2001 - 10:31 #22
Jeg checker lige min kode, og vender tilbage, jeg må indrømme at det var uprøvet det jeg foreslog, så ........ jeg vender som sagt lige tilbage.

/Martin
Avatar billede microtec Nybegynder
03. april 2001 - 10:41 #23
*gg*
Er der noget, der går i \"kage\"?
Så er der nok nogen der leger med en pointer :o)
Avatar billede muttley Nybegynder
03. april 2001 - 11:13 #24
Jubiii !!!

Efter hjælpen fra Martin,  og 5-7 timer´s legen,  har jeg sgu fået det til at virke.. :)

Move(F.Memory^,RomArray,F.Size);

Skulle lige ændres meget lidt..:

Move(F.Memory^,RomArray[1],F.Size);

Det er utroligt så ulogisk det egentligt er,  nu hvor jeg lige tænker på det,  og det er nok derfor jeg var så længe om at prøve lige det..

\"Man skulle jo tro at [1] peger på kun en byte,  men alligevel ligger den det hele i Array´en..  Skummelt\"

Men uden den store hjælp fra Martin,  kunne jeg slet ikke komme nogen steder,  så derfor får han selvfølgelig hans point !!

Mange tak for jeres hjælp...
Avatar billede martinlind Nybegynder
03. april 2001 - 11:19 #25
Hej Igen, så har jeg fundet fejlen *S*

din Move line skal se sådan ud :

Move(F.Memory^,RomArray[0],F.Size);

og husk så lige du skal flytte dit RomArray væk fra procedure Var\'en ellers er data væk når du kommer ud af proceduren, du skal flytte erklæeringen op på Formclassen eller til en Global.

/Martin

Microtec >> Du hygger dig rigtig hva\' *GG*
Avatar billede martinlind Nybegynder
03. april 2001 - 11:25 #26
muttley >> RomArray[1] peger på 1 element, men da delphi lægger alle elementer lige efter hinanden så kan man læse hele klumpen ind med move og første element som start.

/Martn

PS. husk lige for en ordens skyld at ændre det jeg skrev tidligere
Avatar billede microtec Nybegynder
03. april 2001 - 11:26 #27
martinlind >> Hygger nok lidt :o)

Kunne ikke lade være. Det er den slags \"fejl\", hvor hele PC-en vælter om på siden, man oplever når man leger med pointere *gg*
Avatar billede martinlind Nybegynder
03. april 2001 - 11:34 #28
Jeg kører NT, så jeg fik \"auto\" lukket delphi et par gange *S*
Avatar billede muttley Nybegynder
03. april 2001 - 11:38 #29
martinlind >> Og jaja.. :)  Jeg skal nok flytte RomArray væk fra Proceduren,  det jeg viste herinde,  var bare et lille testprogram jeg lavede så jeg kunne afprøve det..

Det ville jo ikke være så skide fedt hvis jeg legede med det i det rigtige program,  da hvis da skulle ske noget,  kunne jeg jo midste det hele.. :)

Lige til sidst,  kan en så utrolig person som dig ikke lige hurtig fortælle hvordan jeg nemmeste får hele RomArray´en ned i en ny fil ??

Eller skal jeg oprette et nyt spørgsmål for at få svar på det ??
Avatar billede martinlind Nybegynder
03. april 2001 - 11:52 #30
Du skal Lave en Ny MemeryStream og sætte dens størelse ( SizeOf(RomArray); ) og så skal du bruge Move ( Move(RomArray[0],F.Memory^,SizeOf(RomArray)); ) til at flytte data ind i den og SaveToFile(<FileName>); til at gemme i en ny fil

Dette burde virke, jeg har dog ikke testet det men mon ikke det virker det vil jeg tro.

/Martin
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
Kurser inden for grundlæggende programmering

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