Ei ole koulutehtävä.
Mikä on [paras] tapa käyttää tietovuon luku/kirjoitus tapahtumiin osoittimia, tarttis koodinpätkän.
Ongelma on lukea ja kirjoittaa lennossa
tiedostosta tiedostoon [saa olla bufferi välissä]
dataa [joka käsitellään jotenkin] tuossa välissä.
En ole osoittimia käyttänyt kuin C :ssa ja
tää delphi on ihan outo ja nyt kuitenkin pakko
käyttää. Taulukoilla hommasta tulee aivan
ihan tahma.
Koodinpätkä delphillä, jos joku viittii, ei tartte
kuitenkaan assembleria, ei ole niin nopeuskriittinen vaan delphi piisaa, eikä ole
edes kauhea kiire, kun vaan äkkiä joku auttaa.
Mikä on [paras] tapa käyttää tietovuon luku/kirjoitus tapahtumiin osoittimia, tarttis koodinpätkän.
Ongelma on lukea ja kirjoittaa lennossa
tiedostosta tiedostoon [saa olla bufferi välissä]
dataa [joka käsitellään jotenkin] tuossa välissä.
En ole osoittimia käyttänyt kuin C :ssa ja
tää delphi on ihan outo ja nyt kuitenkin pakko
käyttää. Taulukoilla hommasta tulee aivan
ihan tahma.
Koodinpätkä delphillä, jos joku viittii, ei tartte
kuitenkaan assembleria, ei ole niin nopeuskriittinen vaan delphi piisaa, eikä ole
edes kauhea kiire, kun vaan äkkiä joku auttaa.
Vastaukset 4
Vanhimmat
Tällainen olisi yksi [hyvä] ja nopea tapa kopioida tiedosto (dataa voi muokatakin välissä):
procedure OmaCopyFile(src,dest: string);
var i: integer; srcSl,destSl: TStringList;
begin
if not FileExists(src) then begin
ShowMessage('Tiedostoa ei löydy'); Exit;
end;
srcSl:=TStringList.Create;
destSl:=TStringList.Create;
srcSl.LoadFromFile(src);
for i:=0 to srcSl.Count-1 do begin
// Tässä voit muuttaa kirjoitettavaa tekstiä
destSl.Add(srcSl.Strings[i]);
end;
destSl.SaveToFile(dest);
srcSl.Free;
destSl.Free;
end;
Tulipas epäselvän näkönen koodi.. no delphiin siirrettäessä selkenee..
Mutta on myös mahdollista käyttää perinteistä Pascal keinoa AssignFile, Reset, ReWrite, Read, Write, CloseFile funktioiden avulla, joilla voi avata useampia tiedostoja yhtä aikaa. Et siis tarvitse välttämättä muuta puskuria kuin string-muuttujan.
Esittämäsi tapa toimii, jos data on merkkijonomuotoista (eli tekstiä) ja se joko mahtuu kokonaan RAMiin, tai kysyjää ei haittaa virtuaalimuistin käyttö RAMin tapaan, jolloin ohjelma toimii hitaasti kun kiintolevy joutuu esittämään olevansa RAM -muistia.
Jos data on binääristä tai sitä on paljon suhteessa RAM -muistin kokoon, katso esittämäni vastaus (TFileStream)
ps. Ne Streamit on myös syytä vapauttaa käytön jälkeen, kas näin:
FS1.FREE;
FS2.Free;
kannattaa myös käyttää try finally -rakennetta, näin varmistat että Streamit vapautetaan aina, tuli poikkeus tai ei!
Sensijaan Stringit ovat Delphissä siitä kivoja, että ne vapautetaan automaattisesti.
Sensijaan TStringList on luokka ja se pitää erikseen vapauttaa.
"Tietovuo" on ainakin minulle outo sana.
Tarkoitatko Streamejä?
Katsopa Delphin helpistä:
TStream
TFileStream
Jos ei ole koulutehtävä, niin pointtereita et tuohon tarvitse ollenkaan!
Käytä Delphin merkkijonoja puskureina!
Kas näin:
var
St1 : String;
FS1, FS2 : TFileStream;
begin
FS1 := TFileStream.Create(SourceName, fmOpenRead);
FS2 := TFileStream.Create(DestName, fmCreate);
// nyt on streamit luotu: Kas näin:
While FS1.Position < FS1.Size do begin
//
L := FS1.Size - FS1.Position;
if L > 4096 then L := 4096;
SetLength(St1,L);
FS1.ReadBuffer(St1[1],L);
// Nyt Stringissä on L merkkiä (=tavua) tiedostosta 1 FS1:n kautta luettua dataa.
// Jos ei muokata, vaan vain kopioidaan, niin:
//
FS2.WriteBuffer(St1[1],L);
end;
Ei toi Delphillä tuon vaikeampaa ole.
Itseasiassa, Pointtereita tarvitaan Delphissä hyvin harvoin! Lähinnä, jos suunnittelet omia komponentteja, niin joissain tapauksissa Pointterien avulla vältät turhaa datan kopiointia, ja näin ohjelmasta tulee nopeampi ja/tai se kuluttaa vähemmän muistia. Myös, jos ohjelmassasi on useita säikeitä, tarkista STrINGien säieturvallisuus käyttämässäsi Delphi versiossa. Eroja voi olla!
HUOMAA: Merkkijonon St1 ensimmäinen merkki on St1[1]
MUTTA:
Jos castaat (eli tyyppimuunnat) tuon PChar -tyyppiseksi (PChar on osoitin C-tyyliseen #0:aan päättyvään merkkijonoon), niin:
var
P : PChar;
P := PChar(St1);
//
St1[1] := 'A';
// Nyt tiedetään, että P[0] on myös 'A' !!!
Siis tuossa PCharissa indeksit alkavat 0:sta.
HUOMAA:
Vain String -tyypissä muistinkäsittely on automaattista. PChar -tyyppiä käytettäessä SINÄ ohjelmoijana olet vastuussa muistin varauksesta ja vapauttamisesta!
Esimerkki siitä, mitä EI saa tehdä:
function Joku(A,B : String):PChar;
var C : String;
begin
C := A B; // Laita A ja B peräkkäin, tulos C:hen
Result := PChar(C);
// VARO! C:String vapautetaan funktiosta poistuttaessa.
// Nyt funktion paluuarvo osoittaa varaamattomaan muistipakikkaan, jossa OLI muuttujan C arvo!
// Funktion paluuarvon käyttäminen saattaa sattumalta toimia, mutta yhtä hyvin se voin antaa roskadataa tai johtaa "Accessa Violation" -virheeseen!
end;
Katso helpistä:
GetMem, FreeMem
StrNew()
StrDispose()
Myös Windows API:sta löytyy:
GlobalAlloc()
GlobalFree()
Tai, jos olet kokenut ohjelmoija ja haluat erottaa muistiavaruuden varauksen ja muistin varauksen toisistaan:
VirtualAlloc
VirtualFree