Care este diferența dintre read() și fread()? (Programare, C, Fișier, Fișier Io)

Georg Schölly a intrebat.

Citesc codul sursă al instrumentului linux badblocks. Se utilizează read() funcția acolo. Există vreo diferență față de standardul C fread() standard C? (Nu pun la socoteală argumentele ca fiind o diferență.)

6 răspunsuri
Darron

read() este o citire de nivel scăzut, fără buffer. Face un apel direct la sistem pe UNIX.

fread() face parte din biblioteca C și oferă citiri cu tampon. De obicei, este implementat prin apelarea read() pentru a-i umple memoria tampon.

Comentarii

  • Deci există 3 tampoane? Harddrive-ul are unul, /dev/hda este și el bufferizat și fread. Este corect acest lucru? –  > Por Georg Schölly.
  • da. îl puteți spăla pe al treilea folosind „fflush”, iar pe al doilea folosind fsync. nu știu o modalitate de a spăla bufferul harddrive-ului. –  > Por Johannes Schaub – litb.
  • fflush() se aplică cu adevărat doar la fwrite(), care are aceeași relație cu write() pe care fread() o are cu read(). –  > Por Darron.
  • @Darron im mai mult un tip Linux și întrebarea era despre Linux. Poate diferi în funcție de sistemul de operare, dar în general se poate presupune că în Linux fread apelează read. –  > Por Jānis Gruzis.
AIB

Familie read() -> open, close, read, write
Familie fread() -> fopen, fclose, fread, fwrite

Familia citește:

  • sunt apeluri de sistem
  • nu sunt formatate IO: avem un flux de octeți neformatat

Familia fread

  • sunt funcții ale bibliotecii standard C (libc)
  • utilizează un buffer intern
  • sunt IO formatate (cu parametrul „%…”) pentru unele dintre ele
  • utilizează întotdeauna memoria cache a bufferului Linux

Mai multe detalii aici, deși rețineți că această postare conține unele informații incorecte.

Comentarii

  • Ultimele două puncte din ambele liste, read și fread, sunt un nonsens. Ambele familii folosesc în mod implicit memoria cache buffer, iar care dintre ele să fie folosită are nimic legătură cu faptul că accesați un dispozitiv de caractere, un dispozitiv de blocuri sau un fișier obișnuit. –  > Por Marcus.
  • AIB confundă două straturi de tamponare – tamponarea din kernel are loc în ambele cazuri (ceea ce aș numi în mod normal memoria cache a bufferului Linux), dar tamponarea care se face în spațiul utilizatorului pentru a reduce numărul total de apeluri de sistem cred că are loc doar cu fread. –  > Por Joseph Garvin.
  • @Marcus Am eliminat cele mai multe dintre concepțiile greșite din răspuns. –  > Por duskwuff -inactiv-.
phihag

read este un syscall, în timp ce fread este o funcție din biblioteca standard C.

Comentarii

  • @Jānis Gruzis, care depinde de implementarea lui fread. În principal, deoarece nu există nicio garanție că apelul de sistem read este disponibil. Wikipedia read pagina –  > Por bzeaman.
  • @JānisGruzis Tocmai am verificat dacă este la fel și pe Windows și spre uimirea mea am descoperit că lor read este depreciat. Probabil că their fread apelează la _read și nu read? În orice caz, se pare că nu fiecare fread trebuie să apeleze read. –  > Por rsp.
Joe

După cum îmi amintesc eu read() API de nivel nu fac bufferizare – deci dacă vă read() 1 octet la un moment dat, veți avea o penalizare uriașă a performanței în comparație cu același lucru cu fread(). fread() va extrage un bloc și îl va distribui pe măsură ce îl cereți. read() va scădea la kernel pentru fiecare apel.

Tor Klingberg

O diferență de care ar trebui să fiți conștienți dacă convertiți codul care folosește unul la celălalt:

  • fread blochează până când numărul de octeți pe care l-ați cerut a fost citit, până când fișierul se termină sau până când apare o eroare.
  • read De asemenea, blochează, dar dacă cereți, de exemplu, 4kB, se poate întoarce după ce a citit doar 1kB, chiar dacă fișierul nu s-a terminat.

Acest lucru poate cauza erori subtile, deoarece depinde de locul în care este stocat fișierul, de memoria cache etc.

chakra t

read() –> Folosirea directă a acestui apel de sistem către kernel și care efectuează operațiunea IO.

fread() –> Este o funcție furnizată în biblioteca standard.

Apelarea fread() este utilizată în principal pentru datele din fișiere binare în care sunt stocate date structurate. Principala diferență între aceste două este numărul de apeluri de sistem din aplicația dvs.

La fread() tip de funcții ale bibliotecii standard IO sunt optimizate pentru apeluri de sistem, mai degrabă aplicația dvs. efectuând apeluri de sistem.