linux c編程:文件的讀寫


Linux系統中提供了系統調用函數open()close()用於打開和關閉一個存在的文件

int open(const char *pathname,int flags)

int open(const char *pathname,int flags,mode_t mode)

int open(const char *pathname,mode_t mode)

其中flag代表文件的打開方式

O_RDONLY: 以只讀方式打開文件

O_WRONLY:以只寫的方式打開文件

O_RDWR:以讀寫的方式打開文件

O_CREAT:若打開的文件不存在,則創建該文件

O_EXCL:如果打開文件是設置了O_CREAT,但是該文件存在,則導致調用失敗

O_TRUNC:如果以只寫或只讀方式打開一個已存在的文件,將該文件截至0

O_APPEND:追加的方式打開文件

O_NONBLOCK:用於非堵塞接口i/o

O_NODELAY

O_SYNC:當數據被寫入外存或者其他設備后,操作才返回。

其中mode是打開的權限

S_IRWXU 00700 設置文件所有者的讀,寫,執行權限

S_IRWXG 00070 設置文件所在用戶組的讀,寫,執行權限

S_IRWXO 00007 設置其他用戶的讀,寫,執行權限

S_IRUSR 00400 設置文件所有者的讀權限

S_IWUSR 00200 設置文件所有的寫權限

S_IXUSR 00100 設置文件所有者的執行權限

S_IRGRP 00040 設置用戶組的讀權限

S_IWGRP 00020 設置用戶組的寫權限

S_IXGRP 00010 設置用戶組的執行權限

S_IROTH 00004 設置其他用戶的讀權限

S_IWOTH 00002 設置其他用戶的寫權限

S_IXOTH 00001 設置其他用戶的執行權限



文件的讀操作:

ssize_t read(int fd,void *buf,size_t count);

fd代表文件描述符,buf代表讀取的數據存放的buf指針所指向的緩沖區,count代表讀取數據的字節數

函數調用成功,返回為讀取的字節數,否則返回-1


文件讀和寫的例子

void open_and_read_file()

{

int fd,n;

char buf[100];

char *path="/home/zhf/zhf/c_prj/c_test.txt";

fd=open(path,O_RDWR);

n=read(fd,buf,20);

printf("the content is %s\n",buf);

}


在這里文件都是從頭開始讀的,那么如果我想從某個位置比如第N個字節開始讀取的時候該如何操作呢,這里就需要用到文件定位函數lseek

off_t lseek(int fildes,off_t offset,int whence);\

fildes是文件描述符

offset是偏移量

whence代表用於偏移時的相對位置,可以取如下的幾個值

SEEK_SET: 從文件的開頭位置計算偏移量

SEEK_CUR: 從當前的位置開始計算偏移量

SEEK_END: 從文件的結尾開始計算偏移量

函數修改如下: 首先采用lseek函數將文件定位到從第11個字節開始,然后read將從第11個字節開始讀取。

對於寫操作也是一樣的。

void open_and_read_file()

{

int fd,n;

char buf[100];

char *path="/home/zhf/zhf/c_prj/c_test.txt";

int i;

fd=open(path,O_RDWR);

i=lseek(fd,11,SEEK_SET);

n=read(fd,buf,20);

printf("the content is %s\n",buf);

close(fd);

}


一個完整的創建,讀,寫文件的例子:

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

void write_file(int fd){
    char buf[]="abcde\n";
    write(fd,buf,sizeof(buf));

    close(fd);
}

void read_file(){
    int fd;
    char *path="/home/zhf/test1.txt";
    char result[20];
    fd=open(path,O_RDONLY);
    read(fd,result,10);
    printf("The content is %s",result);
    close(fd);
}

int create_file(){
    int fd;
    char *path="/home/zhf/test1.txt";
    fd=creat(path,00777);
    return fd;
}


前面介紹的操作都是基於文件描述符的文件操作,下面來介紹基於流的文件操作。兩者有什么區別呢:

緩沖文件系統的特點是:在內存開辟一個“緩沖區”,為程序中的每一個文件使用,當執行讀文件的操作時,從磁盤文件將數據先讀入內存“緩沖區”, 裝滿后再從內存“緩沖區”依此讀入接收的變量。執行寫文件的操作時,先將數據寫入內存“緩沖區”,待內存“緩沖區”裝滿后再寫入文件。由此可以看出,內存 “緩沖區”的大小,影響着實際操作外存的次數,內存“緩沖區”越大,則操作外存的次數就少,執行速度就快、效率高。一般來說,文件“緩沖區”的大小隨機器 而定。主要有fopen, fclose, fread, fwrite, fgetc, fgets, fputc, fputs, freopen, fseek, ftell, rewind
2.
非緩沖文件系統
緩沖文件系統是借助文件結構體指針來對文件進行管理,通過文件指針來對文件進行訪問,既可以讀寫字符、字符串、格式化數據,也可以讀寫二進制數 據。非緩沖文件系統依賴於操作系統,通過操作系統的功能對文件進行讀寫,是系統級的輸入輸出,它不設文件結構體指針,只能讀寫二進制文件,但效率高、速度 快,由於ANSI標准不再包括非緩沖文件系統,因此建議大家最好不要選擇它。本書只作簡單介紹。open, close, read, write, getc, getchar, putc, putchar 等。

open
是系統調用 返回的是文件句柄,文件的句柄是文件在文件描述副表里的索引,fopenC的庫函數,返回的是一個指向文件結構的指針。
linux
中的系統函數是openfopen是其封裝函數。fopen可以移植,open不能



來看fopen函數:FILE *fopen(const char *path,const char *mode)

path代表文件名路徑

mode代表文件的打開方式。有 r,r+,w,w+,a,a+等方式

fgetc()函數:從文件讀取1個字節 int fgetc(FILE *stream). 如果出錯或者讀到文件末尾,則返回EOF

fputc()函數:向指定的文件寫入1個文件 int fputc(int c,FILE *stream);

實例代碼:

void fopen_file()

{

int i;

char ch;

FILE *fp;

char *path="/home/zhf/zhf/c_prj/c_test.txt";

fp=fopen(path,"r");

for(i=0;i<5;i++)

{

if ((ch=fgetc(fp)) != EOF)

{

printf("%c",ch);

}

}

}

fputcfgetc函數只能一次性的讀取或者寫入一個字節,如果想讀取或者寫入一個字符串則需要用到fgets()fputs()函數。

Char *fgets(char *s,int size, FILE *stream);

讀取到’\n’轉移字符為結束,並在該行末尾添加一個’\0’組成完成的字符串。在size字節范圍內沒有讀到’\n’結束符,則添加一個’\0’

int fputs(const char *s, FILE *stream);

void fopen_file()

{

int i;

char ch;

char *str;

FILE *fp;

char *path="/home/zhf/zhf/c_prj/c_test.txt";

char result[100];

fp=fopen(path,"r");

str=fgets(result,20,fp);

printf("%s\n",str);

fclose(fp);

}



同樣的基於流操作的也有文件的定位操作函數分別是fseek函數和rewind函數

int fseek(FILE *stream,long offset,int whence)

這里offset表示移動的字節數,要求位移量是long型數據。以便在文件長度大於64Kb不會出錯

whence和前面介紹的一樣。

rewind函數的作用是使位置指針重新返回文件的開頭,函數沒有返回值。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM