2024(e)ko apirilaren 12(a), ostirala

Fitxategiak: non gaude?








Fitxategi batekin lanean gaudela, hurrengo idazketa/irakurketa zein posiziotan gertatuko da? Beste era batera galdeturik, nola mugitu ahal dugu fitxategiak duen uneko posizioren erakuslea?

Demagun 4 elementuko fitxategi bat daukagula, adibidez hurrengo irudian ematen den zenbaki errealen fitxategia. Fitxategiaren posizioa zein den, eta posizio horri dagokion fitxategiaren elementua zenbatgarrena den kontzeptu desberdinak dira, nahiz eta biak elkar erlazionaturik dauden kontzeptu desberdinak dira. Adibidearen 4 elementuko fitxategiak dituen posizio posibleak 5 dira: 0, 1, 2, 3 eta 4. Eta 5 posizio horietatik, une jakin batean bakarra izango da jasango duen hurrengo idazketa/irakurketa operazioa.

Hurrengo idazketa/irakurketa operazioa fitxategiaren zein posiziotan gertatuko den guk geuk kontrolatu nahi badugu seek prozedura aplikatu beharko dugu. Gogora dakargun seek prozedura estandarra, zeinek bi parametro behar dituen:

  • fitxategia adierazten duen file datu-motako aldagaia
  • helburuko posizioa adierazten duen zenbaki osoa

Jarraian erakusten diren datu-mota eta aldagai hauek ditugula, horiei loturiko seek prozedura estandarraren dei desberdiak azalduko dira:

type
   tfrFitxategia = file of real ;
   tsKatea = string[199] ;

var
   f: tfiFitxategia ;        (* kopuru errealak biltzen dituen fitxategia *)
   rZbk_R: real ;            (* fitxategitik elementu bat irakurtzeko     *)
   rZbk_D: real ;            (* fitxategian elementu bat idazteko         *)
   liPosizioa: longint ;     (* fitxategiaren helburuko posizioa          *)
...

Seek prozeduraren bigarren parametroak har ditzaken balioak 0 eta filesize(f) artekoak izan daitezke (adibidean 0 eta 4 artekoak). Funtsean bi kasu daude:

  1. fitxategiaren filesize(f) bukaeran kokatzea, ala,
  2. fitxategiaren bukaeran ez den beste posizio batean kokatzea. Esate baterako, fitxategiaren lehen elementuaren gainean kokatzea edo fitxategiaren azken-aurreko posizioan kokatzea (fitxategiaren azken elementuaren gainean).


seek(f, filesize(f)) fitxategiaren bukaera

Fitxategiaren azken posizioan elementurik ez dago fitxategiaren bukaera delako. Fitxategiaren bukaeran kokaturik gaudela, ezin daiteke bertatik elementurik irakurri baina bai bertan elementu berri bat idatzi. Elementu berri bat idaztean fitxategiaren tamaina handituko da. Hurrengo adibide-programan ikusi I-A eta I-B kasuak.




seek(f, filesize(f)-1) fitxategiaren azken-aurreko posizioa

Fitxategiaren azken-aurreko posizioa fitxategiaren azken elementuarena da. Fitxategiaren azken-aurreko posizioan  kokaturik gaudela, bertako elementua irakur daiteke eta azken-aurreko posizio horretan idatz daiteke (noski, idazketa burutuko balitz elementu berriak aurrekoa ordezkatuko luke). Hurrengo adibide-programan ikusi II kasua.




seek(f, 0) fitxategiaren lehen posizioa

Fitxategiaren 0 posizioa fitxategiaren lehen elementuarena da. Fitxategiaren 0 posizioan  kokaturik gaudela, bertako elementua irakur daiteke eta 0 posizio horretan idatz daiteke ere (noski, idazketa burutuko balitz elementu berriak aurrekoa ordezkatuko luke). Hurrengo adibide-programan ikusi III kasua.




seek(f, filepos(f)-1) fitxategiaren uneko posizioaren aurrekoa

Fitxategiaren uneko posizioa filepos(f) funtzioaren bitartez ezagut daiteke. Fitxategiaren uneko posiziotik bat atzera egiteko seek(f, filepos(f)-1) agindua idatzi beharko da, jakinik exekuzio-denborako errorea gertatuko litzatekeela fitxategiaren uneko posizioa 0 bada (izan ere, fitxategiaren lehen elementuko aurrekorik ez dago). Hurrengo adibide-programan ikusi IV kasua.


Adibide-programa:

program SeekProzedura ;

uses
   sysutils ;    (* FileExists funtzioak behar duelako *)

const
   sBIDEA = 'C:\Datuak\' ;

type
   tfiFitxategia = file of real ;
   tsKatea = string[199] ;

procedure FitxategiaIkusi(sFitxIzen: tsKatea) ;
var
   f: tfiFitxategia ;
   rElementua: real ;
begin
   { uztartu }
   assign(f, sFitxIzen) ;
   reset(f) ;

   writeln('"', sFitxIzen, '" fitxategiak ', filesize(f), ' elementu ditu, bere edukia:') ;
   while not eof(f) do
   begin
      read(f, rElementua) ;
      writeln(rElementua:10:2) ;
   end ;
   writeln('.....................................................................') ;
   writeln ;
   { itxi }
   close(f) ;
end ;


procedure FitxategiaSortuEtaBete(sFitxIzen: tsKatea) ;
var
   f: tfiFitxategia ;
   rElementua: real ;
   i, kopurua: integer ;
begin
   { uztartu }
   assign(f, sFitxIzen) ;
   rewrite(f) ;

   write('Zenbat elementu nahi dituzu "', sFitxIzen, '" fitxategian? ') ;
   readln(kopurua) ;

   randomize; { random-aren hazia hasieratu }
   for i:=1 to kopurua do
   begin
      rElementua:=random*10 ;   { 0.0 eta 9.9 arteko zenbakia }
      write(f, rElementua) ;    { fitxategian idatzi eta hurrengo elementura pasa }
   end ;
   { itxi }
   close(f) ;
end ;


procedure FitxategiarenElementuBatProzesatu(sFitxIzen: tsKatea) ;
var
   f: tfiFitxategia ;        (* kopuru errealak biltzen dituen fitxategia *)
   rZbk_R: real ;            (* fitxategitik elementu bat irakurtzeko     *)
   rZbk_D: real ;            (* fitxategian elementu bat idazteko         *)
   liPosizioa: longint ;     (* fitxategiaren helburuko posizioa          *)
   cEragiketa: char ;        (* fitxategitik irakurri, fitxategian idatzi *)
   cBaiEz: char ;            (* fitxategiaren azken elementua aldatzeko   *)
begin
   assign(f, sFitxIzen) ;
   reset(f) ;

   repeat
      write('Helburuko posizioa eman (0 eta ', filesize(f), ' ) artekoa: ') ;
      readln(liPosizioa) ;
      if liPosizioa < 0 then
         writeln('Posiziorik txikiena 0 da') ;
      if liPosizioa > filesize(f) then
         writeln('Fitxategiaren bukaera ', filesize(f), ' da') ;
   until (liPosizioa >= 0) and (liPosizioa <= filesize(f)) ;

   repeat
      writeln('Fitxategiaren ', liPosizioa, ' posizioan dagoen elementuarekin zer nahi duzu egin?') ;
      write('Irakurri (R) edo idatzi (D)? ') ;
      readln(cEragiketa) ;
      cEragiketa := upcase(cEragiketa) ;
   until (cEragiketa = 'R') or (cEragiketa = 'D') ;

   writeln ;

   if cEragiketa = 'R' then   (* irakurketa fitxategitik *)
      if liPosizioa = filesize(f) then                             (* I-A kasua *)
         writeln(liPosizioa, ' posiziotik (fitxategiaren bukaeratik) ezin daiteke irakurri')
   else
   begin
      seek(f, liPosizioa) ;
      read(f, rZbk_R) ;
      writeln(rZbk_R:0:2, ' kopurua fitxategiaren ', liPosizioa , ' posizioan') ;
   end ;

   if cEragiketa = 'D' then   (* idazketa fitxategian *)
   begin
      write('Fitxategian idatziko den kopurua eman: ') ;
      readln(rZbk_D) ;

      if liPosizioa = filesize(f) then
      begin
         writeln(liPosizioa, ' posizioan (fitxategiaren bukaeran) idaztean elementu berri bat gehituko zaio fitxategiari') ;
         seek(f, liPosizioa) ;
         write(f, rZbk_D) ;                                        (* I-B kasua *)
      end
      else
      begin
         seek(f, liPosizioa) ;
         read(f, rZbk_R) ;
         writeln('Fitxategiaren ', liPosizioa , ' posizioan dagoen ', rZbk_R:0:2, ' kopurua galduko da') ;
         seek(f, filepos(f)-1) ;                                   (* IV kasua *)
         write(f, rZbk_D) ;
      end ;
   end ;

   seek(f, 0) ;                                                    (* III kasua *)
   writeln('"', sFitxIzen, '" fitxategiaren eduki berria:') ;
   while not eof(f) do
   begin
      read(f, rZbk_R) ;
      writeln(rZbk_R:10:2) ;
   end ;

   repeat
      write(filesize(f)-1, ' posizioko fitxategiaren azken elementua inkrementatu nahi (B/E)? ') ;
      readln(cBaiEz) ;
      cBaiEz := upcase(cBaiEz) ;
   until (cBaiEz = 'B') or (cBaiez = 'E') ;

   writeln ;

   if cBaiEz = 'B' then   (* irakurketa eta idazketa fitxategian *)
   begin
      seek(f, filesize(f)-1) ;                                     (* II kasua *)
      read(f, rZbk_R) ;
      rZbk_D := rZbk_R + 1 ;
      seek(f, filepos(f)-1) ;                                      (* IV kasua *)
      write(f, rZbk_D) ;

      seek(f, 0) ;                                                 (* III kasua *)
      writeln('"', sFitxIzen, '" fitxategiaren eduki berria:') ;
      while not eof(f) do
      begin
         read(f, rZbk_R) ;
         writeln(rZbk_R:10:2) ;
      end ;
   end ;

   close(f) ;
end ;


{============================PROGRAMA NAGUSIA============================}

var
   sIzena: tsKatea ;
begin
   writeln ;
   writeln ;
   writeln('"C:\Datuak" direktorioan lan eginez,') ;
   writeln('fitxategiaren izena eman ezazu (luzapenik gabe)...') ;
   write('Adibidez, "Kopuruak" izena: ') ;
   readln(sIzena) ;
   sIzena := sBIDEA + sIzena + '.dat' ;
   writeln ;

   if fileexists(sIzena) then
   begin
      writeln('"', sIzena, '" fitxategia existitzen da, lan egin dezagun.') ;
      writeln ;
      FitxategiaIkusi(sIzena) ;
      FitxategiarenElementuBatProzesatu(sIzena) ;
   end
   else
   begin
      writeln('"', sIzena, '" fitxategia ez da existitzen, sortuko dugu.') ;
      writeln ;
      FitxategiaSortuEtaBete(sIzena) ;
      FitxategiaIkusi(sIzena) ;
   end ;

   writeln ;
   writeln ('ENTER sakatu programaren exekuzioa amaitzeko...') ;
   readln ;
end.
 

iruzkinik ez:

Argitaratu iruzkina

Iruzkinen bat idazteko Google-ko kontu bat behar duzu. Iruzkin guztien moderazio-ardura blogeko administratzaileari dagokio.