readとwrite関数の使用


ヘッダファイルを含める必要があります.
readシステム関数は、開いたデバイスまたはファイルからデータを読み出し、外付けデバイスからカーネルを介してユーザ空間にデータを読み出す.writeシステム関数は逆に、開いているデバイスやファイルにデータを書き込み、ユーザースペース(I/Oバッファ)からカーネルにデータを送り、外付けデバイスにブラシをかけます.これらの関数のプロトタイプは次のとおりです.
ssize_t read(int fd, void *buf, size_t count);   
ssize_tは符号付き整数、size_tは符号なし整数である.fdは対応するファイル記述子である.bufは、固定サイズではなくcount値によってそのサイズ(ユーザが与えたバイト数)を決定するユーザに与えられたデータバッファである.例えばread(fd,“hello”,5);このときのvoid*bufはchar*タイプです.すなわちcountは、読み出しを要求するバイト数(すなわちbufのサイズ)である.この関数の戻り値が-1の場合、データの読み取りに失敗したことを示します.戻り値>0の場合、読み出したバイト数を示す.戻り値が0に等しい場合は、読み終わったのでデータが読めないことを示します.
ssize_t write(int fd, const void *buf, size_t count);
bufは、出力が必要なバッファであり、ユーザによって与えられる.coutは最大出力バイト数(bufのサイズ、バイト数)である.戻り値が-1の場合、書き込みに失敗しました.>=0の場合、書き込みバイト数を表します.
以上の2つのバッファbufはいずれもユーザ空間のアドレスであるが、I/Oバッファとは異なり後者は所定であり、前者はユーザ自身が指定したものである.
思考:read、writeを利用して1つのByteを読むか書くか、getsとputsを利用して1つのByteを読むか書くか、どちらが速いですか.
readおよびwrite関数はLinuxシステム関数であり、そのバッファはユーザによって維持される.すなわち、ユーザがそのサイズを指定し、ユーザ空間のデータを毎回カーネルに送るか、カーネルからユーザ空間に送るデータのサイズはユーザによって規定される.一方、getsとputsはCライブラリ関数であり、そのI/Oバッファはライブラリ関数によって自分で維持され、サイズは8 Byteであるため、平均的に8つのByteを転送するデータ量ごとにカーネルが操作される.以上のように、データを読み書きする場合、read、write関数は、ユーザ空間から1 byteデータを読み出すたびにカーネル(システム呼び出し)を操作します(オーバーヘッドが大きく、速度が遅くなります.putsとgets関数は高速です.もちろん、readとwriteのcountパラメータを指定してバッファサイズを大きくし、putsとgetsよりも高速に読み書きできます.(大きなファイルでは、より効果的です).
readとwriteの使い方を例に挙げて説明します.
 
//あるファイル(english.txt)の内容を別のファイル(writefile.txt)に読み込む
[root@localhost work]# vim rdwr.c
[root@localhost work]# ls
english.txt  rdwr.c
#include 
#include 
#include 
#include 
#include 
#include 

int main( )
{
    int fd;
    fd = open("english.txt",O_RDONLY);  //       
    printf("open readfile's fd=%d
",fd); if( fd == -1 ) { perror(" open english.txt " ); exit(1); } int fd1; char buff[1024] = { 0 }; // fd1 = read( fd,buff,sizeof(buff) ); // printf("read readfile's fd1=%d
",fd1); if( fd1 == -1 ) { perror(" read english.txt " ); exit(1); } int fd2; fd2 = open( "writefile.txt" ,O_WRONLY | O_CREAT | O_EXCL,0664); // , , , printf("open writefile's fd2=%d
",fd2); if ( fd2 == -1 ) { perror( "creat file" ); exit(1); } int ret; while( fd1 ) { ret = write( fd2,buff,fd1); // if( ret == -1 ) { perror( "write file"); exit(1); } fd1 = read( fd,buff,1024); // if( fd1 == -1 ) { perror(" read english.txt " ); exit(1); } } int qw1; int qw2; qw1=close(fd); // if( ret == -1 ) { perror( "close readfile"); exit(1); } qw2=close(fd2); if( ret == -1 ) { perror( "close writefile"); exit(1); } return 0; }

 [root@localhost work]# gcc -pipe -pedantic -Wall -ggdb3 rdwr.c -o rdwr
[root@localhost work]# ./rdwr
open readfile's fd=3
read readfile's fd1=1024
open writefile's fd2=4
[root@localhost work]# ls
english.txt  rdwr  rdwr.c  writefile.txt
[root@localhost work]# ll writefile.txt
-rwxrwxrwx. 1 root root 109055 Mar 19 11:39 writefile.txt
[root@localhost work]# ll english.txt
-rwxrwxrwx. 1 root root 109055 Mar 19 10:30 english.txt//ファイルサイズが同じ