Файловий ввід-висновок – read і write

Весь введення і виведення здійснюється двома системними викликами – read і write, які доступні з мови Сі через функції з тими ж іменами В обох функціях перший аргумент – це дескриптор файлу Другий аргумент – масив байт, службовець джерелом або приймачем даних Третій аргумент задає кількість переданих байт

int  fd,  n,  nread,  nwritten char  buf[SIZE]

nread  =  read(fd,  buf,  n) nwritten  =  write(fd,  buf,  n)

Обидва виклику повертають кількість фактично переданих байт При читанні повертається число може бути менше очікуваного, якщо до кінця файлу залишилося менше n байт (Якщо файл є терміналом, виклик read зазвичай читає до символу нового рядка, а це, як правило, менше вказаного значення) При досягненні кінця файлу повертається значення 0, а в разі помилки – значення -1 При записи повертається число фактично записаних байт відмінність цього значення від очікуваного говорить про наявність помилки

Хоча кількість байт для читання і запису не обмежується, на практиці найчастіше задається значення 1, тобто посимвольного передача даних (небуферізованних введення-виведення), і значення, рівне раз міру дискового блоку, найчастіше 512 або 1024 (Це значення міститься в константі BUFSIZ у файлі stdioh)

Проілюструємо вищесказане за допомогою програми, що копіює свій введення в висновок Так як введення і виведення можуть бути перенаправлені в будь-який файл або пристрій, ця програма копіює що завгодно куди завгодно: це схематична реалізація команди cat

/ * Cat: мінімальна версія * /

# Define SIZE 512 / * довільне значення * /

main()

{

char  buf[SIZE] int n

while  ((n =  read(0, buf,  sizeof buf))  &gt  0) write(1,  buf, n)

exit(0)

}

Якщо розмір файлу не кратний SIZE, то черговий виклик read поверне менше значення для запису, а наступний після цього виклик read поверне значення 0

Найбільш ефективно читання і запис даних виконуються порціями, рівними розміром дискового блоку, хоча й посимвольного введення-виведення годиться для невеликих обсягів даних, так як ядро ​​саме виконує буферизацію і основні витрати припадають на системні виклики Редактор ed, наприклад, використовує побайтное читання зі стандартного вводу Ми виміряли продуктивність цієї версії cat на файлі довжиною 54000 байт для шести значень SIZE:

Час (користувальницьке + системне, сек)

SIZE

1

PDP-11/70 271,0

VAX-11/750 188,8

10

29,9

19,3

100

3,8

2,6

512

1,3

1,0

1024

1,2

0,6

5120

1,0

0,6

Розмір блоку складає 512 байт в системі PDP-11 і 1024 в системі VAX

Абсолютно нормальна ситуація, коли кілька процесів одночасно звертаються до одного файлу наприклад, один процес записує дані, а інший в цей час їх читає Така поведінка може збивати з пантелику, але іноді буває і корисним Навіть якщо виклик read повернув 0, наступний виклик може виявити нові дані, якщо вони в цей час були записані Цей ефект покладений в основу програми readslow, яка продовжує читання введення незалежно від того, чи досягнуто кінець файлу Програма readslow зручна для спосте дення за процесом виконання програм:

$ slowprog  &gttemp &amp

$ readslow  &lttemp | grep  something

Іншими словами, повільна програма виконує висновок у файл, а програма readslow, можливо, взаємодіючи з якою-небудь іншою програмою, стежить за накопиченням даних

Програма readslow ідентична програмі cat за винятком того, що вона продовжує виконувати цикл після досягнення кінця файлу Тут звернення до низкорівневому вводу-висновку неминуче, тому що функції стандартної бібліотеки продовжують повертати EOF після першого досягнення кінця файлу

/ * Readslow: безперервне читання в очікуванні даних * /

# Define SIZE 512 / * довільне значення * /

main()

{

char  buf[SIZE] int n

for  (;) {

while ((n  =  read(0, buf,  sizeof buf))  &gt  0) write(1,  buf,  n)

sleep(10)

}

}

Функція sleep призупиняє виконання програми на задане число секунд це описано в sleep (3) Не потрібно, щоб readslow тормо шила файл, постійно звертаючись за новими даними це зажадає занадто багато процесорного часу Таким чином, ця версія re-adslow копіює свій введення, досягає кінця файлу і переривається нена довго, потім намагається повторити введення Якщо за час бездіяльності надійшли нові дані, вони будуть лічені при наступному проході

Вправа 71Додайте в програму readslow параметр –n так, щоб функція sleep зупиняла виконання наn секунд У деяких системах команда tail має параметр-f (forever, тобто нескінченно), який включає в команді tail режим, подібний readslow Прокоментуйте це рішення ~

Вправа 72Що станеться з програмою readslow, якщо розмір читаного файлу зменшиться Як це виправити Підказка: прочитайте про fstat в розділі 73 ~

Джерело: Керниган Б, Пайк Р, UNIX Програмне оточення – Пер з англ – СПб: Символ-Плюс, 2003 – 416 с, Мул

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*