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:

1
2
3
4
5
6
7
8
9
10
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
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.