1. 程式人生 > >嵌入式Linux學習筆記第三天(檔案程式設計)

嵌入式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_