2.1Linux文件IO概述
2.1.0POSIX规范
POSIX:(Portable Operating System Interface)可移植操作系统接口规范。
由IEEE制定,是为了提高UNIX(也适用于Linux)环境下应用程序的可移植性。
2.1.1虚拟文件系统
Linux具有与其他操作系统和谐共存的能力。
Linux文件系统由两层构建:第一层是虚拟文件系统(VFS),第二层是各种不同的具体的文件系统。
VFS把各种具体的文件系统的公共部分抽取出来,形成一个抽象层,是系统内核的一部分。
位于用户程序和具体的文件系统之间,为用户程序提供标准的文件系统调用接口。对用户屏蔽底层文件系统的实现细节和差异。
1 nodev sysfs 2 nodev rootfs 3 nodev ramfs 4 nodev bdev 5 nodev proc 6 nodev cpuset 7 nodev cgroup 8 nodev tmpfs 9 nodev devtmpfs 10 nodev debugfs 11 nodev tracefs 12 nodev securityfs 13 nodev sockfs 14 nodev bpf 15 nodev pipefs 16 nodev devpts 17 ext3 18 ext2 19 ext4 20 squashfs 21 nodev hugetlbfs 22 vfat 23 nodev ecryptfs 24 fuseblk 25 nodev fuse 26 nodev fusectl 27 nodev pstore 28 nodev mqueue 29 nodev rpc_pipefs 30 nodev nfs 31 nodev nfs4 32 nodev nfsd
2.1.2 文件和文件描述符
Linux文件系统是基于文件概念的。文件是以字符序列构成的信息载体。可以把IO设备当做文件来处理。
Linux中的文件主要分为6种:普通文件、目录文件、符号链接文件、管道文件、套接字文件和设备文件。
一个进程启动时,都会打开3个流,标准输入、标准输出和标准错误。
对应的文件描述符0、1、2,宏分别STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO。
2.1.3 文件IO和标准IO的区别
1.只要在开发环境中有标准C库,标准IO就可以使用。Linux既可以使用标准IO,也可以使用文件IO。
2.通过文件IO读写文件时,每次操作都会执行相关系统调用。好处:直接读写实际文件。坏处:频繁的系统调用会增加系统开销。
3.文件IO中用文件描述符表示一个打开的文件,可以访问不同类型的文件(普通文件、管道文件、设备文件等)。
标准IO中用FILE(流)表示一个打开的文件,通常只是用来访问普通文件。
2.2文件IO操作
主要介绍文件IO相关函数:open()、read()、write()、lseek()和close()。它们不带缓冲,直接对文件(包括设备)进行读写操作。
2.2.1 文件打开和关闭
打开:
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
说明:open用于创建或打开文件,在打开或创建文件时可以指定文件打开方式及文件的访问权限。
关闭: int close(int fd);
说明:用于关闭一个被打开的文件。当一个进程终止时,所有打开的文件都有内核自动关闭。
很多程序都利用这一特性而不显式地关闭一个文件。
1 /******************************************************************* 2 * > File Name: 01-open.c 3 * > Author: fly 4 * > Mail: XXXXXXXX@icode.com 5 * > Create Time: Sun 03 Sep 2017 09:01:10 PM CST 6 ******************************************************************/ 7 8 #include <stdio.h> 9 #include <sys/types.h> 10 #include <sys/stat.h> 11 #include <fcntl.h> 12 #include <unistd.h> 13 14 int main(int argc, char* argv[]) 15 { 16 int fd; 17 18 if((fd = open("test.txt", O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0){ 19 perror("Fail to open test.txt :"); 20 return (-1); 21 }else{ 22 printf("Succeed to open test.txt, fd = %d ", fd); 23 } 24 25 close(fd); 26 27 return 0; 28 }
1 OPEN(2) Linux Programmer's Manual OPEN(2) 2 3 4 5 NAME 6 open, creat - open and possibly create a file or device 7 8 SYNOPSIS 9 #include <sys/types.h> 10 #include <sys/stat.h> 11 #include <fcntl.h> 12 13 int open(const char *pathname, int flags); 14 int open(const char *pathname, int flags, mode_t mode); 15 16 int creat(const char *pathname, mode_t mode); 17 18 DESCRIPTION 19 Given a pathname for a file, open() returns a file descriptor, a small, nonnegative integer for use in subse‐ 20 quent system calls (read(2), write(2), lseek(2), fcntl(2), etc.). The file descriptor returned by a success‐ 21 ful call will be the lowest-numbered file descriptor not currently open for the process. 22 23 By default, the new file descriptor is set to remain open across an execve(2) (i.e., the FD_CLOEXEC file 24 descriptor flag described in fcntl(2) is initially disabled; the O_CLOEXEC flag, described below, can be used 25 to change this default). The file offset is set to the beginning of the file (see lseek(2)). 26 27 A call to open() creates a new open file description, an entry in the system-wide table of open files. This 28 entry records the file offset and the file status flags (modifiable via the fcntl(2) F_SETFL operation). A 29 file descriptor is a reference to one of these entries; this reference is unaffected if pathname is subse‐ 30 quently removed or modified to refer to a different file. The new open file description is initially not 31 shared with any other process, but sharing may arise via fork(2). 32 33 The argument flags must include one of the following access modes: O_RDONLY, O_WRONLY, or O_RDWR. These 34 request opening the file read-only, write-only, or read/write, respectively. 35 36 In addition, zero or more file creation flags and file status flags can be bitwise-or'd in flags. The file 37 creation flags are O_CLOEXEC, O_CREAT, O_DIRECTORY, O_EXCL, O_NOCTTY, O_NOFOLLOW, O_TRUNC, and O_TTY_INIT. 38 The file status flags are all of the remaining flags listed below. The distinction between these two groups 39 of flags is that the file status flags can be retrieved and (in some cases) modified using fcntl(2). The 40 full list of file creation flags and file status flags is as follows: 41 42 O_APPEND 43 The file is opened in append mode. Before each write(2), the file offset is positioned at the end of 44 the file, as if with lseek(2). O_APPEND may lead to corrupted files on NFS filesystems if more than 45 one process appends data to a file at once. This is because NFS does not support appending to a file, 46 so the client kernel has to simulate it, which can't be done without a race condition. 47 48 O_ASYNC 49 Enable signal-driven I/O: generate a signal (SIGIO by default, but this can be changed via fcntl(2)) 50 when input or output becomes possible on this file descriptor. This feature is available only for 51 terminals, pseudoterminals, sockets, and (since Linux 2.6) pipes and FIFOs. See fcntl(2) for further 52 details. 53 54 O_CLOEXEC (Since Linux 2.6.23) 55 Enable the close-on-exec flag for the new file descriptor. Specifying this flag permits a program to 56 avoid additional fcntl(2) F_SETFD operations to set the FD_CLOEXEC flag. Additionally, use of this 57 flag is essential in some multithreaded programs since using a separate fcntl(2) F_SETFD operation to 58 set the FD_CLOEXEC flag does not suffice to avoid race conditions where one thread opens a file 59 descriptor at the same time as another thread does a fork(2) plus execve(2). 60 61 O_CREAT 62 If the file does not exist it will be created. The owner (user ID) of the file is set to the effec‐ 63 tive user ID of the process. The group ownership (group ID) is set either to the effective group ID 64 of the process or to the group ID of the parent directory (depending on filesystem type and mount 65 options, and the mode of the parent directory, see the mount options bsdgroups and sysvgroups 66 described in mount(8)). 67 68 mode specifies the permissions to use in case a new file is created. This argument must be supplied 69 when O_CREAT is specified in flags; if O_CREAT is not specified, then mode is ignored. The effective 70 permissions are modified by the process's umask in the usual way: The permissions of the created file 71 are (mode & ~umask). Note that this mode applies only to future accesses of the newly created file; 72 the open() call that creates a read-only file may well return a read/write file descriptor. 73 74 The following symbolic constants are provided for mode: 75 76 S_IRWXU 00700 user (file owner) has read, write and execute permission 77 78 S_IRUSR 00400 user has read permission 79 80 S_IWUSR 00200 user has write permission 81 82 S_IXUSR 00100 user has execute permission 83 84 S_IRWXG 00070 group has read, write and execute permission 85 86 S_IRGRP 00040 group has read permission 87 88 S_IWGRP 00020 group has write permission 89 90 S_IXGRP 00010 group has execute permission 91 92 S_IRWXO 00007 others have read, write and execute permission 93 94 S_IROTH 00004 others have read permission 95 96 S_IWOTH 00002 others have write permission 97 98 S_IXOTH 00001 others have execute permission 99 100 O_DIRECT (Since Linux 2.4.10) 101 Try to minimize cache effects of the I/O to and from this file. In general this will degrade perfor‐ 102 mance, but it is useful in special situations, such as when applications do their own caching. File 103 I/O is done directly to/from user-space buffers. The O_DIRECT flag on its own makes an effort to 104 transfer data synchronously, but does not give the guarantees of the O_SYNC flag that data and neces‐ 105 sary metadata are transferred. To guarantee synchronous I/O, O_SYNC must be used in addition to 106 O_DIRECT. See NOTES below for further discussion. 107 108 A semantically similar (but deprecated) interface for block devices is described in raw(8). 109 110 O_DIRECTORY 111 If pathname is not a directory, cause the open to fail. This flag is Linux-specific, and was added in 112 kernel version 2.1.126, to avoid denial-of-service problems if opendir(3) is called on a FIFO or tape 113 device. 114 115 O_EXCL Ensure that this call creates the file: if this flag is specified in conjunction with O_CREAT, and 116 pathname already exists, then open() will fail. 117 118 When these two flags are specified, symbolic links are not followed: if pathname is a symbolic link, 119 then open() fails regardless of where the symbolic link points to. 120 121 In general, the behavior of O_EXCL is undefined if it is used without O_CREAT. There is one excep‐ 122 tion: on Linux 2.6 and later, O_EXCL can be used without O_CREAT if pathname refers to a block device. 123 If the block device is in use by the system (e.g., mounted), open() fails with the error EBUSY. 124 125 On NFS, O_EXCL is supported only when using NFSv3 or later on kernel 2.6 or later. In NFS environ‐ 126 ments where O_EXCL support is not provided, programs that rely on it for performing locking tasks will 127 contain a race condition. Portable programs that want to perform atomic file locking using a lock‐ 128 file, and need to avoid reliance on NFS support for O_EXCL, can create a unique file on the same 129 filesystem (e.g., incorporating hostname and PID), and use link(2) to make a link to the lockfile. If 130 link(2) returns 0, the lock is successful. Otherwise, use stat(2) on the unique file to check if its 131 link count has increased to 2, in which case the lock is also successful. 132 133 O_LARGEFILE 134 (LFS) Allow files whose sizes cannot be represented in an off_t (but can be represented in an off64_t) 135 to be opened. The _LARGEFILE64_SOURCE macro must be defined (before including any header files) in 136 order to obtain this definition. Setting the _FILE_OFFSET_BITS feature test macro to 64 (rather than 137 using O_LARGEFILE) is the preferred method of accessing large files on 32-bit systems (see fea‐ 138 ture_test_macros(7)). 139 140 O_NOATIME (Since Linux 2.6.8) 141 Do not update the file last access time (st_atime in the inode) when the file is read(2). This flag 142 is intended for use by indexing or backup programs, where its use can significantly reduce the amount 143 of disk activity. This flag may not be effective on all filesystems. One example is NFS, where the 144 server maintains the access time. 145 146 O_NOCTTY 147 If pathname refers to a terminal device—see tty(4)—it will not become the process's controlling termi‐ 148 nal even if the process does not have one. 149 150 O_NOFOLLOW 151 If pathname is a symbolic link, then the open fails. This is a FreeBSD extension, which was added to 152 Linux in version 2.1.126. Symbolic links in earlier components of the pathname will still be fol‐ 153 lowed. See also O_NOPATH below. 154 155 O_NONBLOCK or O_NDELAY 156 When possible, the file is opened in nonblocking mode. Neither the open() nor any subsequent opera‐ 157 tions on the file descriptor which is returned will cause the calling process to wait. For the han‐ 158 dling of FIFOs (named pipes), see also fifo(7). For a discussion of the effect of O_NONBLOCK in con‐ 159 junction with mandatory file locks and with file leases, see fcntl(2). 160 161 O_PATH (since Linux 2.6.39) 162 Obtain a file descriptor that can be used for two purposes: to indicate a location in the filesystem 163 tree and to perform operations that act purely at the file descriptor level. The file itself is not 164 opened, and other file operations (e.g., read(2), write(2), fchmod(2), fchown(2), fgetxattr(2), 165 mmap(2)) fail with the error EBADF. 166 167 The following operations can be performed on the resulting file descriptor: 168 169 * close(2); fchdir(2) (since Linux 3.5); fstat(2) (since Linux 3.6). 170 171 * Duplicating the file descriptor (dup(2), fcntl(2) F_DUPFD, etc.). 172 173 * Getting and setting file descriptor flags (fcntl(2) F_GETFD and F_SETFD). 174 175 * Retrieving open file status flags using the fcntl(2) F_GETFL operation: the returned flags will 176 include the bit O_PATH. 177 178 179 * Passing the file descriptor as the dirfd argument of openat(2) and the other "*at()" system calls. 180 181 * Passing the file descriptor to another process via a UNIX domain socket (see SCM_RIGHTS in 182 unix(7)). 183 184 When O_PATH is specified in flags, flag bits other than O_DIRECTORY and O_NOFOLLOW are ignored. 185 186 If the O_NOFOLLOW flag is also specified, then the call returns a file descriptor referring to the 187 symbolic link. This file descriptor can be used as the dirfd argument in calls to fchownat(2), 188 fstatat(2), linkat(2), and readlinkat(2) with an empty pathname to have the calls operate on the sym‐ 189 bolic link. 190 191 O_SYNC The file is opened for synchronous I/O. Any write(2)s on the resulting file descriptor will block the 192 calling process until the data has been physically written to the underlying hardware. But see NOTES 193 below. 194 195 O_TRUNC 196 If the file already exists and is a regular file and the open mode allows writing (i.e., is O_RDWR or 197 O_WRONLY) it will be truncated to length 0. If the file is a FIFO or terminal device file, the 198 O_TRUNC flag is ignored. Otherwise the effect of O_TRUNC is unspecified. 199 200 Some of these optional flags can be altered using fcntl(2) after the file has been opened. 201 202 creat() is equivalent to open() with flags equal to O_CREAT|O_WRONLY|O_TRUNC. 203 204 RETURN VALUE 205 open() and creat() return the new file descriptor, or -1 if an error occurred (in which case, errno is set 206 appropriately). 207 208 ERRORS 209 EACCES The requested access to the file is not allowed, or search permission is denied for one of the direc‐ 210 tories in the path prefix of pathname, or the file did not exist yet and write access to the parent 211 directory is not allowed. (See also path_resolution(7).) 212 213 EDQUOT Where O_CREAT is specified, the file does not exist, and the user's quota of disk blocks or inodes on 214 the filesystem has been exhausted. 215 216 EEXIST pathname already exists and O_CREAT and O_EXCL were used. 217 218 EFAULT pathname points outside your accessible address space. 219 220 EFBIG See EOVERFLOW. 221 222 EINTR While blocked waiting to complete an open of a slow device (e.g., a FIFO; see fifo(7)), the call was 223 interrupted by a signal handler; see signal(7). 224 225 EINVAL The filesystem does not support the O_DIRECT flag. See NOTES for more information. 226 227 EISDIR pathname refers to a directory and the access requested involved writing (that is, O_WRONLY or O_RDWR 228 is set). 229 230 ELOOP Too many symbolic links were encountered in resolving pathname, or O_NOFOLLOW was specified but path‐ 231 name was a symbolic link. 232 233 EMFILE The process already has the maximum number of files open. 234 235 ENAMETOOLONG 236 pathname was too long. 237 238 ENFILE The system limit on the total number of open files has been reached. 239 240 ENODEV pathname refers to a device special file and no corresponding device exists. (This is a Linux kernel 241 bug; in this situation ENXIO must be returned.) 242 243 ENOENT O_CREAT is not set and the named file does not exist. Or, a directory component in pathname does not 244 exist or is a dangling symbolic link. 245 246 ENOMEM Insufficient kernel memory was available. 247 248 ENOSPC pathname was to be created but the device containing pathname has no room for the new file. 249 250 ENOTDIR 251 A component used as a directory in pathname is not, in fact, a directory, or O_DIRECTORY was specified 252 and pathname was not a directory. 253 254 ENXIO O_NONBLOCK | O_WRONLY is set, the named file is a FIFO and no process has the file open for reading. 255 Or, the file is a device special file and no corresponding device exists. 256 257 EOVERFLOW 258 pathname refers to a regular file that is too large to be opened. The usual scenario here is that an 259 application compiled on a 32-bit platform without -D_FILE_OFFSET_BITS=64 tried to open a file whose 260 size exceeds (2<<31)-1 bits; see also O_LARGEFILE above. This is the error specified by POSIX.1-2001; 261 in kernels before 2.6.24, Linux gave the error EFBIG for this case. 262 263 EPERM The O_NOATIME flag was specified, but the effective user ID of the caller did not match the owner of 264 the file and the caller was not privileged (CAP_FOWNER). 265 266 EROFS pathname refers to a file on a read-only filesystem and write access was requested. 267 268 ETXTBSY 269 pathname refers to an executable image which is currently being executed and write access was 270 requested. 271 272 EWOULDBLOCK 273 The O_NONBLOCK flag was specified, and an incompatible lease was held on the file (see fcntl(2)). 274 275 CONFORMING TO 276 SVr4, 4.3BSD, POSIX.1-2001. The O_DIRECTORY, O_NOATIME, O_NOFOLLOW, and O_PATH flags are Linux-specific, and 277 one may need to define _GNU_SOURCE (before including any header files) to obtain their definitions. 278 279 The O_CLOEXEC flag is not specified in POSIX.1-2001, but is specified in POSIX.1-2008. 280 281 O_DIRECT is not specified in POSIX; one has to define _GNU_SOURCE (before including any header files) to get 282 its definition. 283 284 NOTES 285 Under Linux, the O_NONBLOCK flag indicates that one wants to open but does not necessarily have the intention 286 to read or write. This is typically used to open devices in order to get a file descriptor for use with 287 ioctl(2). 288 289 Unlike the other values that can be specified in flags, the access mode values O_RDONLY, O_WRONLY, and 290 O_RDWR, do not specify individual bits. Rather, they define the low order two bits of flags, and are defined 291 respectively as 0, 1, and 2. In other words, the combination O_RDONLY | O_WRONLY is a logical error, and 292 certainly does not have the same meaning as O_RDWR. Linux reserves the special, nonstandard access mode 3 293 (binary 11) in flags to mean: check for read and write permission on the file and return a descriptor that 294 can't be used for reading or writing. This nonstandard access mode is used by some Linux drivers to return a 295 descriptor that is to be used only for device-specific ioctl(2) operations. 296 297 The (undefined) effect of O_RDONLY | O_TRUNC varies among implementations. On many systems the file is actu‐ 298 ally truncated. 299 300 There are many infelicities in the protocol underlying NFS, affecting amongst others O_SYNC and O_NDELAY. 301 302 POSIX provides for three different variants of synchronized I/O, corresponding to the flags O_SYNC, O_DSYNC, 303 and O_RSYNC. Currently (2.6.31), Linux implements only O_SYNC, but glibc maps O_DSYNC and O_RSYNC to the 304 same numerical value as O_SYNC. Most Linux filesystems don't actually implement the POSIX O_SYNC semantics, 305 which require all metadata updates of a write to be on disk on returning to user space, but only the O_DSYNC 306 semantics, which require only actual file data and metadata necessary to retrieve it to be on disk by the 307 time the system call returns. 308 309 Note that open() can open device special files, but creat() cannot create them; use mknod(2) instead. 310 311 On NFS filesystems with UID mapping enabled, open() may return a file descriptor but, for example, read(2) 312 requests are denied with EACCES. This is because the client performs open() by checking the permissions, but 313 UID mapping is performed by the server upon read and write requests. 314 315 If the file is newly created, its st_atime, st_ctime, st_mtime fields (respectively, time of last access, 316 time of last status change, and time of last modification; see stat(2)) are set to the current time, and so 317 are the st_ctime and st_mtime fields of the parent directory. Otherwise, if the file is modified because of 318 the O_TRUNC flag, its st_ctime and st_mtime fields are set to the current time. 319 320 O_DIRECT 321 The O_DIRECT flag may impose alignment restrictions on the length and address of user-space buffers and the 322 file offset of I/Os. In Linux alignment restrictions vary by filesystem and kernel version and might be 323 absent entirely. However there is currently no filesystem-independent interface for an application to dis‐ 324 cover these restrictions for a given file or filesystem. Some filesystems provide their own interfaces for 325 doing so, for example the XFS_IOC_DIOINFO operation in xfsctl(3). 326 327 Under Linux 2.4, transfer sizes, and the alignment of the user buffer and the file offset must all be multi‐ 328 ples of the logical block size of the filesystem. Under Linux 2.6, alignment to 512-byte boundaries suf‐ 329 fices. 330 331 O_DIRECT I/Os should never be run concurrently with the fork(2) system call, if the memory buffer is a pri‐ 332 vate mapping (i.e., any mapping created with the mmap(2) MAP_PRIVATE flag; this includes memory allocated on 333 the heap and statically allocated buffers). Any such I/Os, whether submitted via an asynchronous I/O inter‐ 334 face or from another thread in the process, should be completed before fork(2) is called. Failure to do so 335 can result in data corruption and undefined behavior in parent and child processes. This restriction does 336 not apply when the memory buffer for the O_DIRECT I/Os was created using shmat(2) or mmap(2) with the 337 MAP_SHARED flag. Nor does this restriction apply when the memory buffer has been advised as MADV_DONTFORK 338 with madvise(2), ensuring that it will not be available to the child after fork(2). 339 340 The O_DIRECT flag was introduced in SGI IRIX, where it has alignment restrictions similar to those of Linux 341 2.4. IRIX has also a fcntl(2) call to query appropriate alignments, and sizes. FreeBSD 4.x introduced a 342 flag of the same name, but without alignment restrictions. 343 344 O_DIRECT support was added under Linux in kernel version 2.4.10. Older Linux kernels simply ignore this 345 flag. Some filesystems may not implement the flag and open() will fail with EINVAL if it is used. 346 347 Applications should avoid mixing O_DIRECT and normal I/O to the same file, and especially to overlapping byte 348 regions in the same file. Even when the filesystem correctly handles the coherency issues in this situation, 349 overall I/O throughput is likely to be slower than using either mode alone. Likewise, applications should 350 avoid mixing mmap(2) of files with direct I/O to the same files. 351 352 The behaviour of O_DIRECT with NFS will differ from local filesystems. Older kernels, or kernels configured 353 in certain ways, may not support this combination. The NFS protocol does not support passing the flag to the 354 server, so O_DIRECT I/O will bypass the page cache only on the client; the server may still cache the I/O. 355 The client asks the server to make the I/O synchronous to preserve the synchronous semantics of O_DIRECT. 356 Some servers will perform poorly under these circumstances, especially if the I/O size is small. Some 357 servers may also be configured to lie to clients about the I/O having reached stable storage; this will avoid 358 the performance penalty at some risk to data integrity in the event of server power failure. The Linux NFS 359 client places no alignment restrictions on O_DIRECT I/O. 360 361 In summary, O_DIRECT is a potentially powerful tool that should be used with caution. It is recommended that 362 applications treat use of O_DIRECT as a performance option which is disabled by default. 363 364 "The thing that has always disturbed me about O_DIRECT is that the whole interface is just stupid, and 365 was probably designed by a deranged monkey on some serious mind-controlling substances."—Linus 366 367 BUGS 368 Currently, it is not possible to enable signal-driven I/O by specifying O_ASYNC when calling open(); use 369 fcntl(2) to enable this flag. 370 371 SEE ALSO 372 chmod(2), chown(2), close(2), dup(2), fcntl(2), link(2), lseek(2), mknod(2), mmap(2), mount(2), openat(2), 373 read(2), socket(2), stat(2), umask(2), unlink(2), write(2), fopen(3), fifo(7), path_resolution(7), symlink(7) 374 375 COLOPHON 376 This page is part of release 3.54 of the Linux man-pages project. A description of the project, and informa‐ 377 tion about reporting bugs, can be found at http://www.kernel.org/doc/man-pages/. 378 379 380 381 Linux 2013-08-09 OPEN(2)
2.2.2 文件读写
ssize_t read(int fd, void *buf, size_t count);
说明:read函数从文件中读取数据存放到缓冲区中,并返回实际读取的字节数。若返回0,则表示没有数据可读,
即已达到文件尾。读操作从文件的当前读写位置开始读取内容,当前读写位置自动往后移动。
ssize_t write(int fd, const void *buf, size_t count);
说明:write函数将数据写入文件中,并将返回实际写入的字节数。写操作从文件的当前读写位置开始写入。
对磁盘文件进行写操作时,若磁盘已满,返回失败。
1 /******************************************************************* 2 * > File Name: 02-read.c 3 * > Author: fly 4 * > Mail: XXXXXXXX@icode.com 5 * > Create Time: Sun 03 Sep 2017 09:41:03 PM CST 6 ******************************************************************/ 7 8 #include <stdio.h> 9 #include <sys/types.h> 10 #include <sys/stat.h> 11 #include <fcntl.h> 12 #include <unistd.h> 13 14 #define N 64 15 16 int main(int argc, char* argv[]) 17 { 18 int fd, nbyte, sum = 0; 19 char buf[N]; 20 21 /*1.判断命令行参数*/ 22 if(argc < 2){ 23 printf("Usage : %s <file_name> ", argv[0]); 24 return (-1); 25 } 26 27 /*2.打开文件*/ 28 if((fd = open(argv[1], O_RDONLY)) < 0){ 29 perror("Fail to open :"); 30 return (-1); 31 } 32 33 /*3.循环读取文件,累加读到的字节数*/ 34 while((nbyte = read(fd, buf, N)) > 0){ 35 sum += nbyte; 36 } 37 38 printf("The length of %s is %d bytes ", argv[0], sum); 39 40 close(fd); 41 42 return 0; 43 }
2.2.3文件定位
off_t lseek(int fd, off_t offset, int whence);
offset(@param):相对基准点whence的偏移量,以字节为单位,正数表示向前移动,负数表示向后移动;
whence:SEEK_SET:文件的起始位置;SEEK_CUR:文件的当前读写位置;SEEK_END:文件的结束位置;
说明:lseek函数对文件当前读写位置进行定位。它只能对可定位(可随机访问)文件操作。
管道、套接字和大部分字符设备文件不支持此类访问。
1 /******************************************************************* 2 * > File Name: 05-lseek.c 3 * > Author: fly 4 * > Mail: XXXXXXXX@icode.com 5 * > Create Time: Mon 04 Sep 2017 11:49:08 PM CST 6 ******************************************************************/ 7 8 #include <stdio.h> 9 #include <sys/types.h> 10 #include <sys/stat.h> 11 #include <fcntl.h> 12 #include <unistd.h> 13 #include <stdlib.h> 14 15 #define BUFFER_SIZE (1024*1) /*每次读写缓存大小,影响运行效率*/ 16 #define SRC_FILE_NAME "src_file" /*源文件名*/ 17 #define DEST_FILE_NAME "dst_file" /*目标文件名*/ 18 #define OFFSET (1024*10) /*复制的数据大小*/ 19 20 int main(int argc, char* argv[]) 21 { 22 int fds, fdd; 23 unsigned char buff[BUFFER_SIZE]; 24 int read_len; 25 26 /*1.以只读方式打开源文件*/ 27 if((fds = open(SRC_FILE_NAME, O_RDONLY)) < 0){ 28 perror("Fail to open src_file :"); 29 return (-1); 30 } 31 32 /*2.以只写方式打开目标文件,若此文件不存在则创建,访问权限644*/ 33 if((fdd = open(DEST_FILE_NAME, O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0){ 34 perror("Fail to open dest_file :"); 35 return (-1); 36 } 37 38 /*3.将源文件的读写指针移到最后10KB的起始位置*/ 39 lseek(fds , -OFFSET, SEEK_END); 40 41 /*4.读取源文件的最后10KB数据并写入目标文件,每次读写1KB*/ 42 while((read_len = read(fds, buff, sizeof(buff))) > 0){ 43 write(fdd, buff, read_len); 44 } 45 46 close(fds); 47 close(fdd); 48 49 return 0; 50 }
1 LSEEK(2) Linux Programmer's Manual LSEEK(2) 2 3 4 5 NAME 6 lseek - reposition read/write file offset 7 8 SYNOPSIS 9 #include <sys/types.h> 10 #include <unistd.h> 11 12 off_t lseek(int fd, off_t offset, int whence); 13 14 DESCRIPTION 15 The lseek() function repositions the offset of the open file associated with the file descriptor fd to the 16 argument offset according to the directive whence as follows: 17 18 SEEK_SET 19 The offset is set to offset bytes. 20 21 SEEK_CUR 22 The offset is set to its current location plus offset bytes. 23 24 SEEK_END 25 The offset is set to the size of the file plus offset bytes. 26 27 The lseek() function allows the file offset to be set beyond the end of the file (but this does not change 28 the size of the file). If data is later written at this point, subsequent reads of the data in the gap (a 29 "hole") return null bytes ('