文件I/0
? ? 一個新的的或則一個存在的文件的流能夠通過I/0流的fopen函數。這個fopen函數的取文件名,和打開模式作為參數,和返回對于這流的指針。
? ? FILE* fopen(const char* filename,const char* opentype);
? ? 對于這個fopen函數的第二個參數,這個打開類型,是一個字符串控制文件怎樣被打開。它應該是以下的打開類型之一:
? ? ? r:作為只讀的打開一個存在的文件。
? ? ?w:打開一個只寫的文件。如果這個文件已經存在,它被裁減為0長度。
? ? ?a:打開文件在附加模式。文件內容是被保存,和這新的輸出附加到文件的末尾。如果文件存在,一個新文件被打開。
? ? r+:打開一個讀寫文件。
? ? w+:打開一個讀寫文件模式。如果這個文件已經存在,它被裁減為0長度。
? ?a+:打開這個文件讀和附加。這文件初始化被設置到讀的開始和附加文件的末尾。
? ?如果文件不能用需要的模式的不能被打開,這fopen函數返回一個NULL指針。這例子下,一個流指針,一個FILE指針,為和流的通信被返回,如下:
? ?#include <stdio.h>
...
FILE* stream = fopen("/data/data/com.example.hellojni/test.txt", "w");
if (NULL == stream)
{
/* File could not be opened for writing. */
}
else
{
/* Use the stream. */
/* Close the stream. */
}
寫到流:
? ?Stream I/0提供是個函數來寫到流。這個部分將簡要的瀏覽這些函數。
? ?寫塊數據到流:
? ?這fwrite函數能夠被用來寫塊的數據到流:
? ?size_t fwrite(const void* data, size_t size, size_t count, FILE* stream);
? ?fwite函數寫移動數量的元素到給定的流。
? ?= fwrite(data, sizeof(char), count, stream))
寫字符序列到流:
? ?沒有終止符號的序列使用fputs函數寫到一個流。
??int fputs(const char* data, FILE* stream);
??/* Writing character sequence to stream. */
if (EOF == fputs("hello\n", stream))
{
/* Error occured while writing to the stream. */
}
不能被寫到流,fputs函數將返回EOF。
寫一個單獨字符到流:
? 一個單獨的字符或字節被寫到一個流使用fputc函數:
??int fputc(int c, FILE* stream);
? 如下:這個fputc函數去這單獨的字符作為一個整形數和轉化它到一個無符號的字符寫到這個給定的流,命名的Stream。
? ?char c = 'c';
/* Writing a single character to stream. */
if (c ! = fputc(c, stream))
{
/* Error occured while writing character to string.
}
如果不能被寫到流,fputs函數將返回EOF,否則將返回這字符自己。
寫指定的格式的數據到流中:
? ?這個fprintf函數能夠被用來格式化和輸出變量的參數的的數量到給定的流.
? ?int fprintf(FILE* stream,const char* format,...);
? ?它去一個指針到流,這個格式化字符串,和參數的的變量數目用指定的格式被引用。這個格式字符串有普通的字符串的和 指定格式。普通的格式字符被傳遞不能改到流。指定格式引發這個fprintf函數到個格式和寫這給定的參數到流。這最頻繁使用的自定符如下:
? ? %d,%i:整形參數。%u:無符號。%o:無符號的octal。等
??/* Writes the formatted data. */
if (0 > fprintf(stream, "The %s is %d.", "number", 2))
{
/* Error occurred while writing formatted data. */
}
I/o流提供這個fflush函數使應用程序到自動刷新緩存區被需要。
int fflush(FILE* stream);
如下,這個ffluse函數采用流指針和刷新輸出緩存區的。
? ?char data[] = { 'h', 'e', 'l', 'l', 'o', '\n' };
size_t count = sizeof(data) / sizeof(data[0]);
/* Write data to stream. */
fwrite(data, sizeof(char), count, stream);
/* Flush the output buffer. */
if (EOF == fflush(stream))
{
/* Error occured while flushing the buffer. */
}
從流中讀:
? ?和寫相似,I/0提供了四個函數讀從流中。
? 從流中讀塊的數據
?這fread函數能夠被用來讀塊數據從這個流。
size_t fread(void* data,size_t size,size_t count,FILE* stream);
例如:
??char buffer[5];
size_t count = 4;
/* Read 4 characters from the stream. */
if (count ! = fread(buffer, sizeof(char), count, stream))
{
/* Error occured while reading from the stream. */
}
else
{
/* Null terminate. */
buffer[4] = NULL;
/* Output buffer. */
MY_LOG_INFO("read: %s", buffer);
}
在這個例子,返回的元素數量被傳遞給的值得數量相等。
讀字符序列從流中:
? 這個fgets函數被用來讀一個換行終止符號的字符字符串來自給定的流。
? char* fgets(char* buffer,int count,FILE* stream);
這個fgets函數讀最多count-1個字符和包含這個換行符在字符數組從給定的命名流中。
char buffer[1024];
/* Read newline terminated character sequence from the stream. */
if (NULL == fgets(buffer, 1024, stream))
{
/* Error occured while reading the stream. */
}
else
{
MY_LOG_INFO("read: %s", buffer);
讀單個字符:
unsigned char ch;
int result;
/* Read a single character from the stream. */
result = fgetc(stream);
if (EOF == result)
{
/* Error occured while reading from the stream. */
}
else
{
/* Get the actual character. */
ch = (unsigned char) result;
}
If end-of-file indicator for the stream is set, it returns EOF
讀指定格式的字符:
char s[5];
int i;
/* Stream has "The number is 2" */
/* Reads the formatted data. */
if (2 ! = fscanf(stream, "The %s is %d", s, &i))
{
/* Error occured while reading formatted data. */
}
檢查文件的末尾:
當從一個流中讀時,這個feof的函數被用來檢查如果文件結束指定符對于流被設定。
? int feof(FILE* stream);
char buffer[1024];
/* Until the end of the file. */
while (0 == feof(stream))
{
/* Read and output string. */
fgets(buffer, 1024, stream);
MY_LOG_INFO("read: %s", buffer);
fseek函數:
fseek函數使用流指針,這個相似的offset,和這作為這引用點:
? ?SEEK_SET:流的開始。
? ?SEEK_CUR:現在的位置
? SEEK_END:流的結束。
? 例子代碼如下,寫4個字符,重定位返回流的4個字節和重寫他們使用一個不同的字符。/* Write to the stream. */
fputs("abcd", stream);
/* Rewind for 4 bytes. */
fseek(stream, -4, SEEK_CUR);
/* Overwrite abcd with efgh. */
fputs("efgh", stream);
錯誤檢測在這個例子代碼中被忽略。這個fseek函數將返回0,如果這個操作室成功了;否則一個非零的值指示了失敗。
檢測錯誤:
? ?大部分的I/0流函數將返回EOF來指示錯誤和報告文件末尾。這個ferror函數能夠被用來檢測如果一個錯誤被發生了在上一個操作中。
? int ferror(FILE* stream);
/* Check for the errors. */
if (0 ! = ferror(stream))
{
/* Error occured on the previous request. */
}
關閉流:
? 流可以被關閉使用fclose函數。任何緩存的輸出被寫到流,和任何緩存的輸入被拋棄的。
int fclose(FILE* stream);
if (0 ! = fclose(stream))
{
/* Error occured while closing the stream. */
}
這個錯誤指示這緩存的輸出不能寫到流中因為在磁盤上沒有足夠的空間。很好的習慣來檢測fclose函數的返回值。
總結