C Programmēšanas apmācība par brīvpiekļuves failu apstrādi

Cilvēki, kas sazinās ar šifrētiem datiem, izmantojot mākoņdatošanu

Rojs Skots / Getty Images





Neatkarīgi no vienkāršākajām lietojumprogrammām lielākajai daļai programmu ir jālasa vai jāraksta faili. Tas var būt paredzēts tikai konfigurācijas faila lasīšanai, teksta parsētājs vai kaut kas sarežģītāks. Šī apmācība ir vērsta uz brīvpiekļuves failu izmantošanu C.

Brīvpiekļuves faila I/O programmēšana C valodā

binārais fails

D3Damon/Getty Images



Galvenās failu darbības ir šādas:

  • fopen - atveriet failu - norādiet, kā tas tiek atvērts (lasīt/rakstīt) un ierakstīt (binārs/teksts)
  • fclose - aizveriet atvērto failu
  • fread - lasīt no faila
  • fwrite - rakstiet failā
  • fseek/fsetpos — pārvietojiet faila rādītāju uz kaut kur failā
  • ftell/fgetpos — pastāstiet, kur atrodas faila rādītājs

Divi pamata failu tipi ir teksta un binārs. No šiem diviem binārajiem failiem parasti ir vieglāk rīkoties. Šī iemesla dēļ un tāpēc, ka teksta faila nejauša piekļuve nav tas, kas jums jādara bieži, šī apmācība ir paredzēta tikai binārajiem failiem. Pirmās četras iepriekš uzskaitītās darbības attiecas gan uz teksta, gan brīvpiekļuves failiem. Pēdējie divi tikai izlases piekļuvei.



Brīvpiekļuve nozīmē, ka varat pāriet uz jebkuru faila daļu un no tās lasīt vai rakstīt datus, neizlasot visu failu. Pirms gadiem dati tika glabāti lielos datora lentes ruļļos. Vienīgais veids, kā nokļūt līdz punktam lentē, bija nolasīt visu lenti. Tad parādījās diski, un tagad jūs varat tieši nolasīt jebkuru faila daļu.

Programmēšana ar binārajiem failiem

Binārais fails ir jebkura garuma fails, kurā ir baiti ar vērtībām diapazonā no 0 līdz 255. Šiem baitiem nav citas nozīmes atšķirībā no teksta faila, kur vērtība 13 nozīmē pārvadājuma atgriešanos, 10 nozīmē rindas padevi un 26 — beigas. failu. Programmatūrai, kas lasa teksta failus, ir jārisina šīs citas nozīmes.

Binārie faili ir baitu plūsma, un mūsdienu valodas mēdz strādāt ar straumēm, nevis failiem. Svarīgākā daļa ir datu straume, nevis no kurienes tā nāk. InC, varat domāt par datiem vai nu kā failus, vai straumes. Izmantojot nejaušu piekļuvi, varat lasīt vai rakstīt jebkurā faila vai straumes daļā. Izmantojot secīgo piekļuvi, fails vai straume ir jāpārskata no paša sākuma kā liela lente.

Šis koda paraugs parāda vienkāršu bināro failu, kas tiek atvērts rakstīšanai, un tajā ir ierakstīta teksta virkne (char *). Parasti to redzat teksta failā, taču varat rakstīt tekstu binārā failā.



Šis piemērs atver bināro failu rakstīšanai un pēc tam ieraksta tajā char * (virkni). Mainīgais FILE * tiek atgriezts no izsaukuma fopen (). Ja tas neizdodas (fails var pastāvēt un būt atvērts vai tikai lasāms, vai arī faila nosaukumā ir kļūda), tas atgriež 0.

Komanda fopen () mēģina atvērt norādīto failu. Šajā gadījumā tas ir fails test.txt tajā pašā mapē, kurā atrodas lietojumprogramma. Ja failā ir ietverts ceļš, visas slīpsvītras ir jāpalielina. 'c:folder est.txt' ir nepareizs; jums ir jāizmanto 'c:\folder\test.txt'.



Tā kā faila režīms ir “wb”, šis kods tiek ierakstīts binārā failā. Fails tiek izveidots, ja tas neeksistē, un, ja tas pastāv, viss, kas tajā bija, tiek izdzēsts. Ja izsaukums uz fopen neizdodas, iespējams, tāpēc, ka fails bija atvērts vai nosaukumā ir nederīgas rakstzīmes vai nederīgs ceļš, fopen atgriež vērtību 0.

Lai gan jūs varētu vienkārši pārbaudīt, vai ft nav nulle (veiksmīgs), šajā piemērā ir funkcija FileSuccess(), lai to skaidri izdarītu. Operētājsistēmā Windows tas izvada zvana panākumus/neveiksmes un faila nosaukumu. Tas ir nedaudz apgrūtinoši, ja vēlaties veikt veiktspēju, tāpēc varat to ierobežot tikai ar atkļūdošanu. Operētājsistēmā Windows ir maz papildu teksta izvadīšanas sistēmas atkļūdotājam.



Izsaukumi fwrite () izvada norādīto tekstu. Otrais un trešais parametrs ir rakstzīmju lielums un virknes garums. Abi ir definēti kā lielums_t, kas ir neparakstīts vesels skaitlis. Šī zvana rezultāts ir norādītā izmēra vienumu skaita rakstīšana. Ņemiet vērā, ka ar binārajiem failiem, lai gan jūs rakstāt virkni (char *), tas nepievieno nevienu ritošā atgriešanas vai rindiņas padeves rakstzīmi. Ja vēlaties tos, jums tie ir skaidri jāiekļauj virknē.

Failu režīmi failu lasīšanai un rakstīšanai

Atverot failu, jūs norādāt, kā tas jāatver — vai izveidot to no jauna vai pārrakstīt un vai tas ir teksts vai binārs, lasīt vai rakstīt un vai vēlaties tam pievienot. Tas tiek darīts, izmantojot vienu vai vairākus faila režīma specifikācijas, kas ir atsevišķi burti “r”, “b”, “w”, “a” un “+” kopā ar citiem burtiem.



  • r — atver failu lasīšanai. Tas neizdodas, ja fails neeksistē vai to nevar atrast.
  • w — atver failu kā tukšu failu rakstīšanai. Ja fails pastāv, tā saturs tiek iznīcināts.
  • a - Atver failu rakstīšanai faila beigās (pievienojot), nenoņemot EOF marķieri pirms jaunu datu ierakstīšanas failā; tas vispirms izveido failu, ja tas neeksistē.

Pievienojot “+” faila režīmam, tiek izveidoti trīs jauni režīmi:

  • r+ — atver failu gan lasīšanai, gan rakstīšanai. (Failam ir jābūt.)
  • w+ — atver failu kā tukšu failu gan lasīšanai, gan rakstīšanai. Ja fails pastāv, tā saturs tiek iznīcināts.
  • a+ - atver failu lasīšanai un pievienošanai; pievienošanas darbība ietver EOF marķiera noņemšanu pirms jaunu datu ierakstīšanas failā, un EOF marķieris tiek atjaunots pēc rakstīšanas pabeigšanas. Vispirms tiek izveidots fails, ja tas neeksistē. Atver failu lasīšanai un pievienošanai; pievienošanas darbība ietver EOF marķiera noņemšanu pirms jaunu datu ierakstīšanas failā, un EOF marķieris tiek atjaunots pēc rakstīšanas pabeigšanas. Vispirms tiek izveidots fails, ja tas neeksistē.

Failu režīma kombinācijas

Šajā tabulā ir parādītas failu režīmu kombinācijas gan teksta, gan binārajiem failiem. Parasti jūs lasāt no teksta faila vai rakstāt tajā, bet ne abus vienlaikus. Izmantojot bināro failu, varat gan lasīt, gan rakstīt tajā pašā failā. Tālāk esošajā tabulā parādīts, ko varat darīt ar katru kombināciju.

  • r teksts - lasīt
  • rb+ binārs - lasīt
  • r+ teksts - lasīt, rakstīt
  • r+b binārs - lasīt, rakstīt
  • rb+ binārs - lasīt, rakstīt
  • w teksts - rakstīt, izveidot, saīsināt
  • wb binārs — rakstiet, izveidojiet, saīsiniet
  • w+ teksts - lasiet, rakstiet, izveidojiet, saīsiet
  • w+b binārs — lasīt, rakstīt, izveidot, saīsināt
  • wb+ binārs — lasīt, rakstīt, izveidot, saīsināt
  • teksts - raksti, veido
  • ab binārs - rakstīt, izveidot
  • a+ teksts - lasi, raksti, veido
  • a+b binārs - rakstīt, izveidot
  • ab+ binārs - rakstīt, izveidot

Ja vien jūs tikai neveidojat failu (izmantojiet 'wb') vai nelasāt tikai vienu (izmantojiet 'rb'), varat izvairīties no 'w+b' izmantošanas.

Dažas implementācijas pieļauj arī citus burtus. Microsoft , piemēram, ļauj:

  • t - teksta režīms
  • c - apņemties
  • n - neapņemšanās
  • S - kešatmiņas optimizēšana secīgai piekļuvei
  • R — nesekvenciāla kešatmiņa (izlases piekļuve)
  • T - pagaidu
  • D — dzēst/pagaidu, kas nogalina failu, kad tas tiek aizvērts.

Tie nav pārnēsājami, tāpēc izmantojiet tos, riskējot.

Brīvpiekļuves failu krātuves piemērs

Galvenais bināro failu izmantošanas iemesls ir elastība, kas ļauj lasīt vai rakstīt jebkurā faila vietā. Teksta faili ļauj lasīt vai rakstīt tikai secīgi. Ar izplatību lētām vai bezmaksas datubāzēm, piemēram, SQLite unMySQL, samazina vajadzību izmantot nejaušu piekļuvi binārajiem failiem. Tomēr nejauša piekļuve failu ierakstiem ir nedaudz vecmodīga, taču joprojām noderīga.

Piemēra pārbaude

Pieņemsim, ka piemērā parādīts indeksa un datu faila pāris, kas glabā virknes brīvpiekļuves failā. Virknes ir dažāda garuma, un tās tiek indeksētas pēc 0, 1 un tā tālāk.

Ir divas nederīgas funkcijas: CreateFiles() un ShowRecord(int recnum). CreateFiles izmanto char * buferi ar izmēru 1100, lai saglabātu pagaidu virkni, kas sastāv no formāta virknes msg, kam seko n zvaigznītes, kur n mainās no 5 līdz 1004. Tiek izveidoti divi FILE *, abi izmantojot wb filemode mainīgajos ftindex un ftdata. Pēc izveides tie tiek izmantoti, lai manipulētu ar failiem. Abi faili ir

  • indekss.dat
  • dati.dat

Indeksa failā ir 1000 ierakstu tipa indextype; šis ir struktūras indeksa tips, kurā ir divi locekļi pos (tipa fpos_t) un izmērs. Pirmā cilpas daļa:

aizpilda virknes ziņojumu šādi.

un tā tālāk. Tad šis:

aizpilda struktūru ar virknes garumu un punktu datu failā, kur virkne tiks rakstīta.

Šajā brīdī gan indeksa faila struktūru, gan datu faila virkni var ierakstīt attiecīgajos failos. Lai gan tie ir bināri faili, tie tiek rakstīti secīgi. Teorētiski jūs varētu rakstīt ierakstus pozīcijā, kas atrodas ārpus pašreizējā faila beigām, taču tas nav piemērots paņēmiens un, iespējams, nemaz nav pārnēsājams.

Pēdējā daļa ir aizvērt abus failus. Tas nodrošina, ka faila pēdējā daļa tiek ierakstīta diskā. Failu rakstīšanas laikā daudzi ieraksti nenonāk tieši diskā, bet tiek glabāti fiksēta izmēra buferos. Kad ierakstīšana aizpilda buferi, viss bufera saturs tiek ierakstīts diskā.

Failu skalošanas funkcija liek veikt skalošanu, un jūs varat arī norādīt failu skalošanas stratēģijas, taču tās ir paredzētas teksta failiem.

ShowRecord funkcija

Lai pārbaudītu, vai var izgūt jebkuru norādīto ierakstu no datu faila, jums jāzina divas lietas: kur tas sākas datu failā un cik liels tas ir.

Tas ir tas, ko dara indeksa fails. Funkcija ShowRecord atver abus failus, meklē atbilstošo punktu (recnum * sizeof(indextype) un iegūst baitu skaitu = sizeof(index).

SEEK_SET ir konstante, kas norāda, no kurienes tiek veikts fseek. Šim nolūkam ir definētas divas citas konstantes.

  • SEEK_CUR — meklēt attiecībā pret pašreizējo pozīciju
  • SEEK_END — meklēt absolūtu no faila beigām
  • SEEK_SET — meklēt absolūtu no faila sākuma

Varat izmantot SEEK_CUR, lai pārvietotu faila rādītāju uz priekšu pēc lieluma(indeksa).

Pēc datu lieluma un novietojuma iegūšanas atliek tikai tos ienest.

Šeit izmantojiet fsetpos() indeksa.pos veida dēļ, kas ir fpos_t. Alternatīvs veids ir izmantot ftell, nevis fgetpos, un fsek, nevis fgetpos. Pāris fseek un ftell darbojas ar int, savukārt fgetpos un fsetpos izmanto fpos_t.

Pēc ieraksta nolasīšanas atmiņā tiek pievienota nulles rakstzīme , lai to pārvērstu par pareizu c-string . Neaizmirstiet to, pretējā gadījumā jūs saņemsit avāriju. Tāpat kā iepriekš, fclose tiek izsaukts abos failos. Lai gan jūs nezaudēsit datus, ja aizmirsīsit fclose (atšķirībā no rakstīšanas), jums būs atmiņas noplūde.