同樣地,可以把之前的範例f_ctrl.c (Linux C fopen(), fclose(), fread(), fwrite(), fseek(), ftell(), rewind())拿來修改一下,然後把註解移除掉;
// ctrl.c #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <string.h> int main(void) { int fd0 = 0, fd1 = 0; char szTemp[4]; off_t pos = 0L; fd0 = open("Read.TXT", O_RDONLY); if (fd0 == -1) { perror("Open \"Read.TXT\" failed!! \n"); close(fd0); return 1; } fd1 = open("Write.TXT", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (fd1 == -1) { perror("Open \"Write.TXT\" failed!! \n"); close(fd1); return 1; } memset(&szTemp, '\0', sizeof(char) * 4); pos = lseek(fd0, 5L, SEEK_SET); read(fd0, (void *)&szTemp, sizeof(char) * 4); write(fd1, (void *)&szTemp, sizeof(char) * 4); szTemp[4 - 1] = '\0'; printf("Position0: %ld, %s \n", pos, (char *)szTemp); memset(&szTemp, '\0', sizeof(char) * 4); pos = lseek(fd0, -1L, SEEK_CUR); read(fd0, (void *)&szTemp, sizeof(char) * 4); write(fd1, (void *)&szTemp, sizeof(char) * 4); szTemp[4 - 1] = '\0'; printf("Position1: %ld, %s \n", pos, (char *)szTemp); memset(&szTemp, '\0', sizeof(char) * 4); pos = lseek(fd0, -6L, SEEK_END); read(fd0, (void *)&szTemp, sizeof(char) * 4); write(fd1, (void *)&szTemp, sizeof(char) * 4); szTemp[4 - 1] = '\0'; printf("Position2: %ld, %s \n", pos, (char *)szTemp); pos = lseek(fd0, 0L, SEEK_END); printf("The last position: %ld \n", pos); pos = lseek(fd0, 0L, SEEK_SET); printf("The first position: %ld \n", pos); close(fd0); close(fd1); return 0; }首先,要澄清一下,這個範例完全沒有實務上的意義,因為低階的存取,並不是這樣用。寫這樣的範例只是呈現這些函式的用法而已。
低階IO裡面,並沒有類似ftell()和rewind()的函式;不過還是有其他的方法可以達成。
先看一下執行的結果:
Position的位置都不一樣,是因為在ctrl.c中的lseek()所回傳的是「現在的位置」;而f_ctrl.c中的ftell()回傳的是「執行過fread()之後的位置」;
那麼fread()執行過的單位大小是多少?? 就是sizeof(char) * 4,所以兩者之間的執行結果都是差4 (但完全不影響Write.TXT的內容)。
假如,"The last position: "所顯示的是22,而不是21,這是換行字元 ('\n')CRLF (註)的問題,表示你的"Read.TXT"檔案內容是在Windows下產生的,因為Windows下的換行字元是以0x0D, 0x0A的方式呈現,若是在Linux環境下就只有0x0A。
最后,還是附上各個函式的原型宣告;其中比較複雜的是open()的第2個和第3個參數,有興趣的可以自行詳細研究。
int open(char *pathname, int flags);
int open(char *pathname, int flags, mode_t mode);
int close(int fd);
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, void *buf, size_t count);
off_t lseek(int fildes, off_t offset, int whence);
PS:CRLF, CR/LF, Carriage Return / Line Feed, 回車 / 換行, 0x0D / 0x0A, 這是打字機 (Typewriter)的用語。
沒有留言:
張貼留言