寫入
外觀
寫入(write)是由類Unix操作系統內核提供的最為基本的程序。此程序從用戶定義的緩衝中將數據寫入設備或文件,這也是從程序中使用系統調用直接輸出數據的主要方式。待寫入的地點由文件描述符定義;要寫入的數據(如文本)由指針和大小(字節數)定義。
write
也因此需要三個參數:
POSIX用法
[編輯]寫入調用接口[1][2]根據POSIX規範定義。通過調用寫入函數,數據才能寫入文件。此函數的原型為:
ssize_t write(int fd, const void *buf, size_t nbytes);
參數 | 描述 |
---|---|
fd
|
根據調用打開函數獲取的文件描述符。此參數是一個可為0、1或2整數值,其值分別代表了標準輸入、標準輸出和標準錯誤。 |
buf
|
指向字符陣列,其內容為fd參數指向的文件。 |
nbytes
|
指定從字符陣列寫入fd參數指向的文件的字節數。 |
在上述語法中,ssize_t
是一個typedef
(定義於stddef.h
中帶符號的數據類型)。但注意write()
會在發生錯誤的時候返回-1(參見下方的錯誤一節),故其一定會返回帶符號的值。
寫入函數將返回成功寫入數組的字節數,即意味着有時此值將小於指定的nbytes。
使用示例
[編輯]#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
int main_gg (int argc, char *argv[])
{
int fd1;
char buf[128];
fd1 = open(argv[1], O_WRONLY);
if (fd1 == -1) {
perror(argv[1]);
return EXIT_FAILURE;
}
/* 输入待写入至文件的数据 */
scanf("%127s", buf);
write(fd1, buf, strlen(buf)); /* fd1为文件描述符,buf为用于存储数据的字符阵列,strlen(buf)用于通知函数缓冲中需要复制的字符串字节长度 */
close(fd1);
return 0;
}
操作錯誤
[編輯]下方列出的是在寫入文件時可能會發生的錯誤[3][4]。這些錯誤為errno.h中列出的宏命令。
錯誤數字 | 錯誤 | 意義 |
---|---|---|
4
|
EINTR
|
系統調用中斷。 |
5
|
EIO
|
低級錯誤,通常與硬件的讀取/寫入操作有關。 |
9
|
EBADF
|
文件描述符fd無效,或是正嘗試寫入打開為「只讀」模式的文件。 |
13
|
EACCES
|
用戶沒有寫入文件的所需權限。 |
14
|
EFAULT
|
函數中指定的地址無效。 |
22
|
EINVAL
|
函數傳遞的參數無效。 |
27
|
EFBIG
|
指定於nbytes中的文件大小過大,且大於系統所允許的值。 |
28
|
ENOSPC
|
待寫入至的存儲設備上的存儲空間不足。 |
32
|
EPIPE
|
管道損壞,或是在管道另一端的文件不可用於I/O(大多數拋出此錯誤的進程同時會產生SIGPIPE信號)。 |
調用寫入的高級I/O函數
[編輯]雖然看起來很像,但寫入系統調用不是一個普通的函數。例如在x86架構上的Linux系統上,此系統調用會使用INT 80H指令以將控制權轉移給內核。[5]寫入系統調用,及其配對函數讀取(read)均是只能理解字節的低級函數。寫入函數不可用於寫入記錄(如類)。因此,此時通常需要高級的輸入輸出函數(如printf)。通常與混亂的低級接口相比,程序員更偏好使用高級接口。這些函數在內部調用其他函數,反之也可做出寫入調用,進而打造出了分層函數組合。[6]
有了這種組合,高級函數可收集數據的字節並隨後寫入文件。
參見
[編輯]- fwrite
- getchar
- fprintf
- pwrite ()
- read (system call)
- sync (Unix)
參考文獻
[編輯]- ^ https://www.gnu.org/s/hello/manual/libc/I_002fO-Primitives.html#I_002fO-Primitives (頁面存檔備份,存於網際網路檔案館) I/O Primitives
- ^ 存档副本. [2019-05-03]. (原始內容存檔於2018-10-10).
- ^ https://www.gnu.org/s/hello/manual/libc/Error-Codes.html (頁面存檔備份,存於網際網路檔案館) GNU C Library Manual
- ^ http://www.ibm.com/developerworks/aix/library/au-errnovariable/ (頁面存檔備份,存於網際網路檔案館) IBM page listing errors
- ^ LINUX assembly language programming By Bob Neveln
- ^ http://ftp.gnu.org/gnu/glibc/ (頁面存檔備份,存於網際網路檔案館) GNU C Library Download