1. 程式人生 > >【Linux庫函式程式設計】檔案程式設計

【Linux庫函式程式設計】檔案程式設計

庫函式:所謂庫函式,就是獨立於作業系統的,為提高程式的可移植性而生的一種方式。

無論在什麼作業系統上都可以使用這些函式。

流:    上節課的 【Linux系統呼叫】檔案程式設計 的操作方式為I/O檔案操作,這是C提供的一種檔案操作,它是通過直接存取檔案來完成對檔案的處理。 

而今天的這課是流式檔案操作,流是標準的c函式庫裡的一個抽象概念。當我們讀寫資料時,就會開啟一個流,這個流可以通向檔案、記憶體、

網路連線等,資料可以‘流’向目的地。

檔案指標:在系統呼叫中使用檔案描述符來指向一個檔案,這是I/O操作的實現方式。同理,在流式檔案操作中,使用

檔案指標來指向一個開啟的檔案,型別為FILE*.

一、函式學習:fopen,fclose,fread,fwrite,fseek。

二、最佳實踐:編寫copy程式

一、函式學習

1、fopen: 開啟流

1)函式原型

        FILE *fopen(const char *path, const char *mode);

2)所屬標頭檔案

        #include <stdio.h>

3)返回值

        成功: 返回檔案指標

        失敗: NULL

4)引數說明

        path: 包含路徑的檔名(可以是相對路徑或絕對路徑)

        mode: 開啟模式

                *r: 只讀

                *r+: 可讀可寫   

                *w: 若檔案存在, 清空檔案內容; 若檔案不存在,新建檔案,只寫

                *w+: 若檔案存在,清空檔案內容;若檔案不存在,新建檔案,可讀可寫

                *a: 以追加方式開啟檔案(追加內容寫在檔案尾),若檔案不存在,新建一 個檔案

                *a+: 以可讀、追加方式開啟檔案. 讀檔案的初始位置為檔案頭, 追加到的位置為檔案尾.

#include <stdio.h>


void main()
{
	FILE *fptr = NULL;

	if ( NULL == (fptr = fopen("./fopen-file", "r")) )
	{
		printf("Can not open the file !\n");
		return;
	}

	fclose(fptr);
}
2、fread: 讀資料

1)函式原型

        size_t fread(void *ptr, size_t size, size_t nmenb, FILE *stream);
2)所屬標頭檔案

        #include <stdio.h>
3)返回值

        成功: 成功讀取的元素個數

        失敗: 0

4)引數說明

        ptr: 儲存讀取資料的指標

        size: 每個元素的位元組數

        nmenb: 讀取的元素個數

        stream: 待讀取的檔案指標

#include <stdio.h>

void main()
{
	FILE *fp = NULL;
	char buf[100];
	int num_items = 0;

	fp = fopen("./fread-file", "r");

	num_items = fread(buf, 1, 100, fp);
	buf[num_items] = '\0';

	printf("# %d is read: %s\n", num_items, buf);

	close(fp);
}


3、fclose: 關閉流

1)函式原型

        int fclose(FILE *fp);

2)所屬標頭檔案

        #include <stdio.h>

3)返回值

        成功: 0

        失敗: EOF (End Of File, 檔案尾)

4)引數說明

        fd: 待關閉的檔案指標

4、fwrite: 寫資料

1)函式原型

        size_t fwrite(const void *ptr, size_t size, size_t nmenb, FILE *stream);

2)所屬標頭檔案

        #include <stdio.h>

3)返回值

        成功: 成功寫入的元素個數

        失敗: 0

4)引數說明

        ptr: 儲存待寫入資料的指標

        size: 每個元素的位元組數

        nmenb: 待寫入的元素個數

        stream: 待寫入的檔案指標

#include <stdio.h>

void main()
{
	char *str = "I love linux";
	FILE *fp;

	fp = fopen("./fwrite-file", "w+");

	fwrite(str, 2, 5, fp);

	close(fp);
}


5、fseek: 定位檔案流的偏移量

1)函式原型

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

2)所屬標頭檔案

        #include <stdio.h>

3)返回值

        成功: 0

        失敗: -1

4)引數說明

        stream: 檔案指標

        offset: 偏移量

        whence: 偏移位置(SEEK_SET, SEEK_CUR, SEEK_END, 詳細可看上一篇文章)

二、最佳實踐:copy程式

#include <stdio.h>

void main(int argc, char* argv[])
{
	FILE *fp_src = NULL;
	FILE *fp_dest = NULL;
	int count = 0;
	char buf[65];


	/* 1. Open source and destination files. */
	if ( NULL == (fp_src = fopen(argv[1], "r")) )
	{
		puts("ERROR: File is not exist or can not open.");
		return;
	}
	if (NULL == (fp_dest = fopen(argv[2], "w")) )
	{
		puts("ERROR: Can not creat dest-file.");
		return;
	}

	/* 2. Copy data. */
	while ( (count = fread(buf, 1, 64, fp_src)) > 0)
	{
		fwrite(buf, 1, count, fp_dest);
	}

	/* 3. Close source and destinatin files. */
	fclose(fp_dest);
	fclose(fp_src);
}