嵌入式Linux學習筆記第三天(檔案程式設計)
嵌入式Linux學習筆記第三天
——檔案程式設計
嵌入式Linux檔案程式設計有兩種方式:系統呼叫和庫函式。常用的檔案操作函式有,open、read、write、lseek。通常來說,當一個程序執行時,都會自動開啟三個檔案:標準輸入(鍵盤)、標準輸出(螢幕)、標準出錯處理(螢幕)。這三個檔案對應的檔案描述符分別為0、1、2.(對應的巨集為STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO)。
一:系統呼叫:
所謂的系統呼叫其實就是作業系統提供給使用者程式呼叫的一組“特殊的介面”,使用者程式可以通過這個特殊的介面獲得作業系統核心提供的服務。那麼,為啥作業系統不直接讓使用者直接訪問核心,還搞出個“特殊的介面”,Linux操作在安全方面考慮的比較周到,為了更好的保護核心空間,將程式執行空間分為使用者空間(0-3G)和核心空間(3G-4G),它們分別執行在不同的等級上,在邏輯上是相互分離的。通常情況系,使用者程序在通常情況下不允許訪問核心資料,也就不能訪問核心函式,它們只能操作使用者資料,呼叫使用者函式。下面介紹幾個常用的函式。Creat() , open(), close(),read(), write(), lseek().
1:建立檔案:int creat(const char *filename, mode_t mode)
所需標頭檔案:#include<sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
Filename為建立檔案的檔名(包含路徑,預設是預設為當前路徑),
Mode為建立的檔案屬性,S_IRUSR 可讀
S_IWUSR 可寫
S_IXUSR 可執行
S_IRWXU 可讀可寫可執行
或者是用數字表示,0無任何許可權,1可執行,2可寫,4可讀,6可讀可寫;
要建立一個使用者可讀、可寫、可執行,但是組沒有許可權,其他人可以讀、可以執行的檔案,並設定使用者ID位。那麼,我們應該使用的模式是1(設定使用者ID)、0(不設定組ID)、7(1+2+4,讀、寫、執行)、0(沒有許可權)、5(1+4,讀、執行)即10705:
參考程式:
#include <stdio.h>
#include <stblib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
viod creat_file(char *filename) {
/*建立的檔案具有什麼樣的屬性?*/
if(creat(filename,0755)<0){
printf(“creat file %sfailure!\n”,filename);
exit(EXIT_FAILURE);
} else {
printf(“creat file %ssuccess!\n”,filename);
}
}
int main(int argc,char *argv[]) {
int i;
if(argc<2){
perror("you haven'tinput the filename,please try again!\n");
exit(EXIT_FAILURE);
}
for(i=1;i<argc;i++){
create_file(argv[i]);
}
exit(EXIT_SUCCESS);
}
2:開啟檔案:int open(const char*pathname, flags, mode _t mode)
所需標頭檔案:#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
pathname:被開啟檔名(可包括路徑名,預設時為當前目錄)
flags:檔案開啟的方式,引數可以通過“|”組合構成,但前3個引數不能互相重合。
O_REONLY:只讀方式開啟檔案
O_WRONLY:可寫方式開啟檔案
O_RDWR:讀寫方式開啟檔案
O_CREAT:如果檔案不存在時就建立一個新檔案,並用第三個引數為其設定許可權。
O_EXCL:如果使用O_CREAT時檔案存在,則可返回錯誤資訊。這一引數可測試檔案是否存在。
O_NOCTTY:使用本引數時,如檔案為終端,那麼終端不可以作為呼叫open()系統呼叫的那個程序的控制終端。
O_TRUNC:如檔案已經存在,並且以只讀或只寫成功開啟,那麼會先全部刪除檔案中原因資料。
O+APPEND:以新增方式開啟檔案,在開啟檔案的同時,檔案指標指向檔案末尾。
mode _t mode:被開啟檔案的存取許可權,為8進製表示法(呼叫O_CREAT才需要)。
函式返回值:成功:返回檔案描述符
失敗:-1
3:關閉檔案:int close(int fd)
所需標頭檔案:#include<unistd.h>
fd 為檔案描述符,
函式返回值: 成功:0
出錯:-1
例程:#include<stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc ,char *argv[]){
int fd;
if(argc<2){
puts("please inputthe open file pathname!\n");
exit(1);
}
//如果flag引數裡有O_CREAT表示,該檔案如果不存在,系統則會建立該檔案,該檔案的許可權由第三個引數決定,此處為0755
//如果flah引數裡沒有O_CREAT引數,則第三個引數不起作用.此時,如果要開啟的檔案不存在,則會報錯.
//所以fd=open(argv[1],O_RDWR),僅僅只是開啟指定檔案
if((fd=open(argv[1],O_CREAT|O_RDWR,0755))<0){
perror("open file failure!\n");
exit(1);
}else{
printf("open file %d success!\n",fd);
}
close(fd);
exit(0);
}
4:讀取檔案 int read(int fd, void *buf,size_t length)
所需標頭檔案:#include<unistd.h>
函式傳入值
fd:檔案描述符
buf:指定儲存器讀出資料的緩衝區
size_t length:指定讀出的位元組數
函式返回值:成功:讀出的位元組數0:已到達檔案尾 -1:出錯
在讀普通檔案時,若讀到要求的位元組數之前已達到檔案的尾部,則返回位元組數會小於希望讀出的位元組數。
5:寫入檔案:int write(int fd,void*buf,size_t length)
所需標頭檔案:#include<unistd.h>
函式傳入值:
fd:檔案描述符
Buf:指定儲存器寫入資料的緩衝區
length:指定讀出的位元組數
函式返回值:成功:已寫的位元組數-1:出錯
6:、偏移函式:int lseek(int fd,off_t offset,int whence)
所需標頭檔案:#include<unistd.h>
#include<sys/types.h>
函式傳入值:
fd:檔案描述符
Offset:偏移量,每一讀寫操作所需要移動的距離,單位是位元組的數量,可正可負(向前移,向後移)
Whence:當前位置的基點:
SEEK_SET:當前位置為檔案開頭,新位置為偏移量的大小
SEEK_CUR:當前位置為檔案指標位置,新位置為當前位置加上偏移量
SEEK_END:當前位置為檔案的結尾,新位置為檔案的大小加上偏移量大小
返回值: 成功:檔案相對開頭的當前位移
出錯:-1
二:庫函式程式設計
C庫函式的檔案操作實際上是獨立於具體的作業系統平臺的,不管是在DOS、
Windows、Linux還是在VxWorks中都是這些函式:
1:建立和開啟: FILE *fopen(const char *filename,const char *mode)
所需標頭檔案:#include<stdio.h>
函式傳入值:
Filename:開啟的檔名(包含路徑,預設時為當前路徑)。
Mode:開啟模式,C語言中支援的開啟模式如下表
其中b用於區分二進位制檔案和文字檔案,這一點在DOS、Windows系統中是有區分的,但Linux不區分二進位制檔案和文字檔案。
返回值: 成功:指向file的指標
失敗:NULL
2:關閉檔案:int fclose(FILE *stream)
需標頭檔案 |
#include<stdio.h> Stream:已開啟的檔案指標。 |
函式說明 |
fclose()用來關閉先前fopen()開啟的檔案。此動作會讓緩衝區內的資料寫入檔案中,並釋放系統所提供的檔案資源。 |
返回值 |
成功:返回0, 錯誤:返回EOF並把錯誤程式碼存到errno。 |
例程: #include<stdio.h>
int main()
{
FILE *fp;
fp = fopen(“HELLO.c”,”a++”);
if(fp == NULL) return 0;
fclose(fp);
}
3:讀取檔案:size_t fread(void *ptr,size_t size,size_tn, FILE *stream)
所需標頭檔案:#include <stdio.h>
函式傳入值:
Ptr:存放讀入資料的快取區
Size_t size :每段讀取的記錄大小
Size_t n:讀取的段數,
Stream:要讀取的檔案流(對應檔案指標)
返回值: 成功:返回實際讀取到的n數目
失敗:EOF
例程:
#include<stdio.h>
#define nmemb 3
struct test
{
char name[20];
int size;
}s[nmemb];
main()
{
FILE * stream;
int i;
stream = fopen(“/tmp/fwrite”,”r”);
fread(s,sizeof(struct test),nmemb,stream);
fclose(stream);
for(i=0;i<nmemb;i++)
printf(“name[%d]=%-20s:size[%d]=%d\n”,i,s[i].name,i,s[i].size);
}
執行結果
name[0]=Linux! size[0]=6
name[1]=FreeBSD! size[1]=8
name[2]=Windows2000 size[2]=11
4:寫入檔案:size_t fwrite(const void *ptr,size_t size,size_t n, FILE * stream)
所需標頭檔案:#include <stdio.h>
函式傳入值:
Ptr:存放讀入資料的快取區
Size_t size :每段讀取的記錄大小
Size_t n:讀取的段數,
Stream:要寫入的檔案流(對應檔案指標)
返回值: 成功:返回實際讀取到的n數目
失敗:EOF
例程:
#include<stdio.h>
#define set_s (x,y){strcoy(s[x].name,y);s[x].size=strlen(y);}
#define nmemb 3
struct test
{
char name[20];
int size;
}s[nmemb];
main()
{
FILE * stream;
set_s(0,”Linux!”);
set_s(1,”FreeBSD!”);
set_s(2,”Windows2000.”);
stream=fopen(“/tmp/fwrite”,”w”);
fwrite(s,sizeof(structtest),nmemb,stream);
fclose(stream);
}
5:由檔案中讀取一個字元:int getc(FILE * stream);
所需標頭檔案:#include <stdio.h>
函式傳入值:
Stream:要讀取的檔案流(對應檔案指標)
函式說明:fgetc()從引數stream所指的檔案中讀取一個字元。若讀到檔案尾而無資料時便返回EOF。
返回值: 成功:讀取到的字元
失敗:EOF(已到檔案尾)
例程: #include<stdio.h>
main()
{
FILE *fp;
int c;
fp=fopen(“exist”,”r”);
while((c=fgetc(fp))!=EOF)
printf(“%c”,c);
fclose(fp);
}
6:由檔案中寫入一個字元:int fputc(int c,FILE * stream)
所需標頭檔案:#include <stdio.h>
函式傳入值:
Stream:要寫入的檔案流(對應檔案指標)
返回值: 成功:寫入的字元
失敗:EOF
例程:#include<stdio.h>
main()
{
FILE * fp;
chara[26]=”abcdefghijklmnopqrstuvwxyz”;
int i;
fp= fopen(“noexist”,”w”);
for(i=0;i<26;i++)
fputc(a[i],fp);
fclose(fp);
}
7:移動檔案流的讀寫位置:int fseek(FILE * stream,long offset,intwhence);
所需標頭檔案:#include <stdio.h>
函式傳入值:
Stream:要移動的檔案流(對應檔案指標)
Offset:移動的相對量
Whence為移動的參考量。為下列其中一種:
SEEK_SET從距檔案開頭offset位移量為新的讀寫位置。SEEK_CUR 以目前的讀寫位置往後增加offset個位移量。
SEEK_END將讀寫位置指向檔案尾後再增加offset個位移量。
當whence值為SEEK_CUR 或SEEK_END時,引數offset允許負值的出現。
下列是較特別的使用方式:
1) 欲將讀寫位置移動到檔案開頭時:fseek(FILE*stream,0,SEEK_SET);
2) 欲將讀寫位置移動到檔案尾時:fseek(FILE *stream,0,0SEEK_END);
函式說明:
fseek()用來移動檔案流的讀寫位置。引數stream為已開啟的檔案指標,引數offset為根據引數whence來移動讀寫位置的位移數。
返回值: 成功:0
失敗:-1
附加說明:fseek()不像lseek()會返回讀寫位置,因此必須使用ftell()來取得目前讀寫的位置。
例程:
#include<stdio.h>
main()
{
FILE * stream;
long offset;
fpos_t pos;
stream=fopen(“/etc/passwd”,”r”);
fseek(stream,5,SEEK_SET);
printf(“offset=%d\n”,ftell(stream));
rewind(stream);
fgetpos(stream,&pos);
printf(“offset=%d\n”,pos);
pos=10;
fsetpos(stream,&pos);
printf(“offset =%d\n”,ftell(stream));
fclose(stream);
}
執行結果
offset = 5
offset =0
offset=10
8:格式化輸出資料至檔案:int fprintf(FILE * stream, const char *format,.......);
所需標頭檔案:#include <stdio.h>
函式說明
fprintf()會根據引數format字串來轉換並格式化資料,然後將結果輸出到引數stream指定的檔案中,直到出現字串結束('\0')為止。
返回值: 成功:實際輸出的字元數,
失敗:-1,錯誤原因存於errno中。
例程:
#include<stdio.h>
main()
{
int i = 150;
int j = -100;
double k = 3.14159;
fprintf(stdout,”%d %f %x \n”,j,k,i);
fprintf(stdout,”%2d %*d\n”,i,2,i);
}
執行
-100 3.141590 96
150 150
9:格式化字串輸入:int fscanf(FILE * stream ,const char*format,....);
所需標頭檔案:#include <stdio.h>
函式說明
fscanf()會自引數stream的檔案流中讀取字串,再根據引數format字串來轉換並格式化資料。格式轉換形式請參考scanf()。轉換後的結構存於對應的引數內。
返回值: 成功:引數數目,
失敗:-1,錯誤原因存於errno中。
例程:
#include<stdio.h>
main()
{
int i;
unsigned int j;
char s[5];
fscanf(stdin,”%d%x %5[a-z] %*s %f”,&i,&j,s,s);
printf(“%d %d %s\n”,i,j,s);
}
執行
10 0x1b aaaaaaaaabbbbbbbbbb /*從鍵盤輸入*/
10 27 aaaaa
10:取得當前的工作目錄:char * getcwd(char * buf,size_t size)
所需標頭檔案:#include<unistd.h>
函式說明
getcwd()會將當前的工作目錄絕對路徑複製到引數buf所指的記憶體空間,引數size為buf的空間大小。在呼叫此函式時,buf所指的記憶體空間要足夠大,若工作目錄絕對路徑的字串長度超過引數size大小,則回值NULL,errno的值則為ERANGE。倘若引數buf為NULL,getcwd()會依引數size的大小自動配置記憶體(使用malloc()),如果引數size也為0,則getcwd()會依工作目錄絕對路徑的字串程度來決定所配置的記憶體大小,程序可以在使用完此字串後利用free()來釋放此空間。
返回值:成功:將結果複製到引數buf所指的記憶體空間,
或 是返回自動配置的字串指標。
失敗:NULL,錯誤程式碼存於errno。
例程:
#include<unistd.h>
main()
{
char buf[80];
getcwd(buf,sizeof(buf));
printf(“currentworking directory : %s\n”,buf);
}
執行
current workingdirectory :/tmp
相關推薦
嵌入式Linux學習筆記第三天(檔案程式設計)
嵌入式Linux學習筆記第三天 ——檔案程式設計 嵌入式Linux檔案程式設計有兩種方式:系統呼叫和庫函式。常用的檔案
嵌入式Linux學習筆記(三)檔案程式設計
一、系統呼叫-建立 int creat(const char *filename,mode_t mode) filename:要建立的檔名(包含路徑,預設為當前路徑) mode:建立模式 常見建立模式: S_IRUSR 可讀
Linux學習筆記第三周第一次課(2月5日)
etc col .com mark ueditor bin shell 信息 互傳 2.27linux和windows互傳文件用xshell軟件#yum install -y lrzszlinux傳到windows,命令為#sz a.txt 按提示保存到windowswin
Linux學習筆記第三周第二次課(2月6日)
gid ins 目錄 隨機 useradd 生成 echo tab 設置 3.4 usermod命令更改用戶屬性usermod,更改UID,命令為#usermod -u 編號;更改GID,命令為#usermod -g 編號;更改用戶家目錄,命令為#usermod -d 編號
Linux學習筆記第三周第三次課(2月7日)
配置 學習筆記 使用 con log 搜索 su命令 去掉 start 3.7 su命令root用戶切換到普通用戶命令,su;完全徹底切換 - ,連環境變量,家目錄也切換,命令為#su - aming;查看當前登陸用戶,命令為#whoami;查看當前目錄,命令為#pwd;查
Linux學習筆記第三周第四次課(2月8日)
虛擬機 添加磁盤 acer cto process ued fault print rep 4.1 df命令df,report file system disk space usage匯報文件系統磁盤空間使用情況;df命令格式:df [選項]df -a:all 顯示所有文件
python學習筆記第三天
for map 編程 www com wiki ont 通過 進入 函數的參數 局部變量和全局變量 遞歸函數和匿名函數 高階函數 函數式編程了解 一、函數的各種參數 關鍵參數和位置參數:只要記住關鍵參數必須要放在位置參數後面就行了 #參數問題 def test(x,
hibernate學習筆記第三天
delet unique lis 多少 update 從數據 將不 不同的 get方法 復習環境搭建配置->工廠->Session->事務Query list uniqueResultCriteria(QBC)配置---------------------
Oracle 學習筆記第三天
Oracle 學習筆記第三天 這陣子一堆亂七八糟的事,一直沒有繼續學Oracle,不過快速看了一本Oracle的PDF的書,但是看得速度過快,導致還是一知半解,現在來好好整理一下。 現在表已經建好了,約束也加了,現在準備插入資料。 插入資料的方式有很多,現在資料量不大,我先記錄一
C++學習筆記——第三天運算子和表示式
目標 掌握C++支援的各種運算子和應用 掌握C++支援的由各種運算子和常量變數構成的表示式,語句及其應用 運算子 C++中包含了C語言中的運算子和表示式,並且又增加了一些新的運算子。 ::作用域運算子 new動態分配記憶體單元運算子 delete刪除動態分配的記憶體單元運算
Linux學習筆記第四周第三次課(2月28日)
/word ?word $ P G 5.5 進入編輯模式進入編輯模式,按i(光標處插入),I(移到行首插入),o(光標行下一行插入),O(光標行上一行插入 ),a(光標處後一個字符插入),A(移到行尾插入);5.6 vim命令模式shift+n向上查找;指定範圍內替換,命令為:n1,n2s
Linux學習筆記第五周第三次課(3月7日)
yum list | grep zsh history tab鍵 alias wc -l 8.1 shell介紹每個用戶都有自己的shell;Bourne人名,為了紀念他;搜索zsh命令,#yum list | grep zsh搜索ksh命令,#yum list | grep ksh邏輯判
Linux學習筆記第七周三次課(3月21日)
iptables netfilter INPUT OUTPUT ifconfig 10.11 Linux網絡相關ifconfig -a可以顯示禁止或down掉的網卡;啟動網卡#ifup ens33;禁掉網卡#ifdown ens33;網卡配置文件 /etc/sysconfig/networ
Linux學習筆記第八周三次課(3月28日)
rsync --daemon rsync -avLP iptables -nvl logrotate last 10.32/10.33 rsync通過服務同步關閉防火墻,#systemctl stop firewalld查看iptables規則,#iptables -nvl測試遠程主機87
python學習筆記第9天《檔案的管理辦法》
1,檔案路徑: 絕對路徑:d:\programfiles\python3.exe 即從根目錄開始一直向下找到的檔案 相對路徑:從當前檔案路徑開始的路徑名稱2,編碼方式:utf-8,gbk,unicode等等 檔案是用什麼格式寫的,就得用什麼檔案去讀!否則就會產生亂碼或者
【自學筆記】0基礎自學機器學習 (第三天)
“資料”是機器學習的基礎。 初學機器學習時,我們通常處理的資料格式通常是以下的形式: 屬性(特徵) 幾室 幾廳 供暖(0地熱 1暖氣)
韋東山嵌入式Linux學習筆記之——第12課第8節 字元裝置驅動程式之定時器防抖動
注:本文部分內容摘自《魚樹學員筆記》。 當按鍵按得比較快的時候,這裡出現了兩次中斷值,也即產生了抖動。 這裡產生了“抖動”,按鍵是機械開關,按下鬆開時裡面的金屬彈片可能抖動了好幾次。這種抖動產生了多次“脈衝”導致多次中斷。 方法: 使用定時器來防抖動。
嵌入式Linux學習筆記(三) 字元型裝置驅動--LED的驅動開發
在成功構建了一個能夠執行在開發板平臺的系統後,下一步就要正式開始應用的開發(這裡前提是有一定的C語言基礎,對ARM體系的軟/硬體,這部分有疑問可能要參考其它教程),根據需求仔細分解任務,可以發現包含的外設有LED,BEEP,RS232,六軸感測(SPI介面),光環境感測器(I2C),音訊輸出, RTC等,
linux基礎知識-第三天
linux基礎知識一、環境變量PATH$PATH:決定了shell將到哪些目錄中尋找命令或程序,PATH的值是一系列目錄,當您使用某個命令時,Linux在這些目錄中尋找具體的命令程序。[[email protected]/* */ ~]# echo $PATH/application/mysql/
工作流筆記第三天_流程實例
asc etc 一個 can helloword time system sel inpu 0、流程實例的表 -- 流程實例,執行對象,任務-- 1、解析.bpmn後得到的流程定義規則的信息,工作流系統就是按照流程定義的規則執行的。select * FROM act_ru_