原地址:http://blog.csdn.net/a8887396/article/details/9009363
1 認識文件的描述符號
不允許訪問內核設備和內存但可以通過內核系統函數去訪問
但對每個內核對象進行編號ID:
如果訪問內核對象,只能通過ID
編程模型:
申請得到一個ID
在內核系統函數中使用ID得到對應的內核對象數據
2 怎麼訪問文件
使用函數 傳遞一個文件 系統打開文件 加載文件 返回ID使用函數 傳遞ID 得到數據
使用函數傳遞ID 告訴系統釋放文件
ID:文件描述符 file description (fd)
每個程序執行時都有個目錄存放打開的文件描述符 /proc/${pid}/fd
其中默認開啓0 1 2 三個對象
0 標準輸出
1 標準輸入
2 錯誤輸出
其實它們打開的都是同一個文件(只是打開方式不同而已)
lrwx------ 1 zhao zhao 64 2013-05-30 07:21 0 -> /dev/pts/0
lrwx------ 1 zhao zhao 64 2013-05-30 07:21 1 -> /dev/pts/0
lrwx------ 1 zhao zhao 64 2013-05-30 07:21 2 -> /dev/pts/0
3 操作文件描述符
寫文件#include <unistd.h>
ssize_t write(int fd,
const void *buf, //寫入內核對象
size_t count);//寫入數據大小
返回:
>0 實際寫入的數據個數
-1 寫入錯誤
讀文件
ssize_t read(int fd,
void *buf, //返回數據的空間
size_t count);//空間大小
返回:
>0 :實際讀取的文具
=0 碰到文件結束符號EOF (ctrl+d)
-1 讀取錯誤
基於文件的描述符號
1得到文件描述符
a文件類型普通文件 -
目錄文件 d
鏈接文件 l
管道文件 p
套接字文件 s
字符設備文件 c
塊設備文件 b
find / -type c 查找字符設備文件
b文件屬性
1屬性的表達方式:絕對模式 字符模式
擁有者 組用戶 其他用戶
2文件的權限屬性:
讀
寫
執行
粘附位 :t
設置位權限 :s
t粘附位(防止有寫權限的用戶刪除文件)
1:表示粘附設置
t對寫文件有意義
無效的粘附位使用T表示
chmod o+t xxx
s設置位(向其他用戶開放擁有者權限的權限)
2:組設置位
4:組用戶設置位
s對執行有效
無效的設置位使用S表示
chmod u+s xxx
比如程序員a 寫了個程序可以讀寫文件txt, 這時用戶b來使用程序,但用戶b沒有對文件的讀寫權限,這時就會出錯.
假如程序員給程序設置了設置位, b在使用程序時也會獲得和a一樣的權限.
2通過文件描述符讀寫數據
open函數#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, //文件名
int flags,//open的方式(創建/打開)
mode_t mode);// 文件屬性,創建的時候有效
返回值
>=0 返回內核文件描述符
=-1 打開/創建失敗
open的方式
必選方式: O_RDONLY O_WRONLY O_RDWR 必選一個
創建; O_CREATE
可選方式:
對打開可選方式 : O_APPEND 追加 O_TRUNC 清空數據
對創建可選方式 : O_EXCL 與O_CREATE共用時 ,若文件存在時打開失敗
組合:
創建 O_RDWR | O_CREATE 讀寫打開,若不存在創建
O_RDWR | O_CREATE | O_EXCL 創建文件且讀寫打開 若已文件存在打開失敗
打開 O_RDWR 打開
O_RDWR|O_APPEND 追加打開
O_RDWR|O_TRUNC 截斷打開
文件屬性:
建議使用8進制數
文件創建的實際屬性受到權限屏蔽(umask)的影響
umask //顯示屏蔽屬性
umake 0666 //設置權限屏蔽 就是說創建0777的文件 實際只有0111
關閉文件
void close(int fd);
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdio.h>
- int main()
- {
- int fd;
- char name[20];
- short age;
- float score;
- char sex;
- //創建一個新文件 若文件存在 錯誤
- fd = open("date.dat",O_RDWR|O_CREAT|O_EXCL,0666);
- if(fd < 0)
- {
- perror("open");
- return 1;
- }
- //以便讀取 設置名字爲5字節的字符串
- memcpy(name,"tom ",sizeof("tom "));
- age = 18;
- score = 99.0;
- sex = 'f';
- write(fd,name,sizeof("tom "));
- write(fd,&age,sizeof age);
- write(fd,&score,sizeof score);
- write(fd,&sex,sizeof sex);
- memcpy(name,"jack",sizeof("jack"));
- age=20;
- score=98;
- sex='f';
- write(fd,name,sizeof("jack"));
- write(fd,&age,sizeof(short));
- write(fd,&score,sizeof(float));
- write(fd,&sex,sizeof(char));
- lseek(fd,0,SEEK_SET); //移動文件指針
- read(fd,name,5);
- read(fd,&age,sizeof age);
- read(fd,&score,sizeof score);
- read(fd,&sex,sizeof sex);
- printf("name:%s age:%d score:%f sex %c\n",name,age,score,sex);
- read(fd,name,5);
- read(fd,&age,sizeof age);
- read(fd,&score,sizeof score);
- read(fd,&sex,sizeof sex);
- printf("name:%s age:%d score:%f sex %c\n",name,age,score,sex);
- close(fd);
- }
- /*
- zhao@ubuntu:~/unix/3$ ./open
- name:tom age:18 score:99.000000 sex f
- name:jack age:20 score:98.000000 sex f
- */
3文件描述符號和重定向
isatty(int fd)
判斷文件描述符是否與終端綁定
返回1 文件描述符與終端有關
返回0 不是終端
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdio.h>
- int main()
- {
- int fd;
- printf("hello\n");
- write(1,"world\n",6);
- fd = open("/dev/tty",O_WRONLY);
- if(isatty(fd))
- {
- write(1,"notredir\n",9);
- }
- else
- {
- write(1,"redir\n",6);
- }
- write(fd,"killer\n",7);
- }