1.寫(write)
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
int main()
{
int fd = open("file",O_WRONLY|O_CREAT,0644);//以只寫方式打開或不存在的話創建
if(fd < 0)
{
perror("open");
return 1;//程序失敗
}
const char* msg = "hello world!\n";
int count = 5;
while(count--)//往文件裏寫5條程序
{
write(fd,msg,strlen(msg));
}
close(fd);//關閉文件
return 0;
}
編譯通過會產生一個file,運行,打開file會看到5個hello world!
有幾個文件描述符默認是被佔用的(默認被打開),接下來將write()函數裏的第一個參數改爲“1”,默認往顯示器上寫。
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
int main()
{
int fd = open("file",O_WRONLY|O_CREAT,0644);//以只寫方式打開或不存在的話創建
if(fd < 0)
{
perror("open");
return 1;//程序失敗
}
const char* msg = "hello world!\n";
int count = 5;
while(count--)//往顯示器上寫5條程序
{
write(1,msg,strlen(msg));
}
close(fd);//關閉文件
return 0;
}
所以程序一旦運行起來,就是往顯示器上寫。
所以以後再往顯示器上寫的時候除了printf,又多了一個系統調用接口,write。本質上訪問文件是要通過系統調用接口中的文件描述符來訪問。
2.讀(read)
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
int main()
{
int fd = open("file",O_RDONLY,0644);//以只讀方式打開
if(fd < 0)
{
perror("open");
return 1;//程序失敗
}
const char* msg = "hello world\n";
int size = sizeof(msg);
char buf[64];
int count = 5;
while(count--)//從文件裏讀
{
read(fd,buf,size);//從fd裏讀,將讀到的內容寫到buf裏
printf("%s",buf);
}
close(fd);//關閉文件
return 0;
}
以上代碼的運行結果會出現一些問題
因爲我們在寫文件的時候沒有把‘\0’寫入,但在讀的時候不一定會加上
修改代碼:
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
int main()
{
int fd = open("file",O_RDONLY,0644);//以只讀方式打開
if(fd < 0)
{
perror("open");
return 1;//程序失敗
}
const char* msg = "hello world\n";
int size = strlen(msg);
char buf[64];
while(1)//從文件裏讀
{
size_t s = read(fd,buf,size);//從fd裏讀,將讀到的內容寫到buf裏
if(s > 0)//如果s大於零說明讀成功了,如果讀成功了代表的含義是實際讀了多少
{
buf[s] = 0;//把最後一個元素設置爲零
}
else if(s == 0)//如果返回值爲0則讀到文加結尾
{
break;
}
printf("%s",buf);
}
close(fd);//關閉文件
return 0;
}
如果把read()函數的第一個參數改爲‘0’,代表標準輸入,一旦程序運行起來就會停在那裏等用戶輸入。
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
int main()
{
int fd = open("file",O_RDONLY,0644);//以只讀方式打開
if(fd < 0)
{
perror("open");
return 1;//程序失敗
}
const char* msg = "hello world\n";
int size = strlen(msg);
char buf[64];
while(1)//從文件裏讀
{
size_t s = read(0,buf,size);//將讀到的內容寫到buf裏
if(s > 0)//如果s大於零說明讀成功了,如果讀成功了代表的含義是實際讀了多少
{
buf[s] = 0;//把最後一個元素設置爲零
}
else if(s == 0)//如果返回值爲0則讀到文加結尾
{
break;
}
printf("%s",buf);
}
close(fd);//關閉文件
return 0;
}
最後以ctrl+d結尾。ctrl+d相當於讀到文件結尾,讀到文件結尾就直接break。
3.現在接口認識完了,那麼現在我們來了解一下文件描述符的分配
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
int main()
{
int fd = open("file",O_RDONLY,0644);//以只讀方式打開
if(fd < 0)
{
perror("open");
return 1;//程序失敗
}
printf("fd : %d\n",fd);
return 0;
}
運行結果:
也可以多試幾個:
首先touch 3個文件:file1 file2 file3
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
int main()
{
int fd = open("file",O_RDONLY,0644);//以只讀方式打開
if(fd < 0)
{
perror("open");
return 1;//程序失敗
}
int fd1 = open("file1",O_RDONLY,0644);
int fd2 = open("file2",O_RDONLY,0644);
int fd3 = open("file3",O_RDONLY,0644);
printf("fd : %d\n",fd);
printf("fd : %d\n",fd1);
printf("fd : %d\n",fd2);
printf("fd : %d\n",fd3);
return 0;
}
說明文件描述符的分配確實是從0開始的小整數
如果還是不能確定那再來一段測試代碼:
把‘0’和‘2’關掉(不能關‘1’,若關了就不能顯示出來,但有可以管的方法,後續會提到)
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
int main()
{
close(0);
close(2);
int fd = open("file",O_RDONLY,0644);//以只讀方式打開
if(fd < 0)
{
perror("open");
return 1;//程序失敗
}
int fd1 = open("file1",O_RDONLY,0644);
int fd2 = open("file2",O_RDONLY,0644);
int fd3 = open("file3",O_RDONLY,0644);
printf("fd : %d\n",fd);
printf("fd : %d\n",fd1);
printf("fd : %d\n",fd2);
printf("fd : %d\n",fd3);
return 0;
}
因爲‘1’沒有關所以沒有‘1’。
小結:
這裏所有的函數必須用到文件描述符,文件描述符默認從‘0’開始分配,而實際上‘0’、‘1’、‘2’已經被佔用,分別對應stdin(標準輸入)、stdout(標準輸出)、stderr(標準錯誤)。用戶分配默認從‘3’開始