本文已参与「新人创作礼」活动,一起开启掘金创作之路。
Linux下对文件的读取
接上一篇对文件读取不到的解决方案二:
通过man手册查找lseek,得到如下内容:
NAME lseek - reposition read/write file offset
SYNOPSIS #include <sys/types.h> #include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
DESCRIPTION lseek() repositions the file offset of the open file description associated with the file descriptor fd to the argument offset according to the directive whence as follows:
SEEK_SET
The file offset is set to offset bytes.
SEEK_CUR
The file offset is set to its current location plus offset bytes.
SEEK_END
The file offset is set to the size of the file plus offset bytes.
lseek() allows the file offset to be set beyond the end of the file (but this does not change the size of the file). If data is later written at this point, subsequent reads of the data in the gap (a "hole") return null bytes('\0') until data is actually written into the gap.
修改后的代码如下:
1 #include<stdio.h>
2 #include<sys/types.h>
3 #include<sys/stat.h>
4 #include<fcntl.h>
5 #include<unistd.h>
6 #include<string.h>
7 #include<stdlib.h>
8
9 int main()
10 {
11 int fd;
12 char *buf="I love you the way you are!\n";
13 fd=open("./file1",O_RDWR);
14
15 if(fd==-1){
16 printf("open file1 failed\n");
17 fd =open("./file1",O_RDWR|O_CREAT,0600);
18 if(fd>0){
19 printf("create file1 success!\n");
20
21 }
22 }
23 printf("open success: fd=%d\n",fd);
24 //ssize_t write(int fd,const void *buf,size_t count);
25 int n_write=write(fd,buf,strlen(buf));
26 if(n_write!=-1){
27 printf("Write %d bytes to file1\n",n_write);
28 }
29 //close(fd);
30 //fd=open("./file1",O_RDWR);
31 char *readBuf;
32 readBuf=(char*)malloc(sizeof(char)*n_write+1);
33 //ssize_t read(int fd,void *buf,size_t count);
34 lseek(fd,0,SEEK_SET);//通过SEEK_SET以及偏移量为0回到开始
35 //lseek(fd,-n_write,SEEK_CUR);
36 //lseek(fd,-n_write,SEEK_END);
37 //三种方式都可以解决
38 int n_read=read(fd,readBuf,n_write);
39 printf("read %d ,context:%s\n",n_read,readBuf);
40 close(fd);
41 return 0;
42 }
运行结果均如下图所示:
Linux文件创建
man 手册查阅open的使用方式,如下:
NAME open, openat, creat - open and possibly create a file
SYNOPSIS #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
int creat(const char *pathname, mode_t mode);
int openat(int dirfd, const char *pathname, int flags);
int openat(int dirfd, const char *pathname, int flags, mode_t mode);
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
openat():
Since glibc 2.10:
_POSIX_C_SOURCE >= 200809L
Before glibc 2.10:
_ATFILE_SOURCE
DESCRIPTION The open() system call opens the file specified by pathname. If the speci‐ fied file does not exist, it may optionally (if O_CREAT is specified in flags) be created by open().
The return value of open() is a file descriptor, a small, nonnegative integer
that is used in subsequent system calls (read(2), write(2), lseek(2),
fcntl(2), etc.) to refer to the open file. The file descriptor returned by a
successful call will be the lowest-numbered file descriptor not currently
open for the process.
By default, the new file descriptor is set to remain open across an execve(2)
(i.e., the FD_CLOEXEC file descriptor flag described in fcntl(2) is initially
disabled); the O_CLOEXEC flag, described below, can be used to change this
default. The file offset is set to the beginning of the file (see lseek(2)).
A call to open() creates a new open file description, an entry in the system- wide table of open files. The open file description records the file offset and the file status flags (see below). A file descriptor is a reference to an open file description; this reference is unaffected if pathname is subse‐ quently removed or modified to refer to a different file. For further details on open file descriptions, see NOTES.
The argument flags must include one of the following access modes: O_RDONLY,
O_WRONLY, or O_RDWR. These request opening the file read-only, write-only,
or read/write, respectively.
In addition, zero or more file creation flags and file status flags can be
bitwise-or'd in flags. The file creation flags are O_CLOEXEC, O_CREAT,
O_DIRECTORY, O_EXCL, O_NOCTTY, O_NOFOLLOW, O_TMPFILE, and O_TRUNC. The file
status flags are all of the remaining flags listed below. The distinction
between these two groups of flags is that the file creation flags affect the
semantics of the open operation itself, while the file status flags affect
the semantics of subsequent I/O operations. The file status flags can be
retrieved and (in some cases) modified; see fcntl(2) for details.
参数说明:
int open(const char *pathname,int flags);
int open(const char *pathname,int flags,mode_t mode);
pathname:要打开的文件名(含路径,缺省为当前路径)
Flags:
O_RDONLY 只读打开 O_WRONLY 只写打开 O_RDWR 可读可写打开
当我们附带了权限后,打开的文件就只能按这种权限来操作
以上这三个常数中应当只指定一个。下列常数是可选择的:
O_CREAT 若文件不存在则创建它,使用此选项时,需要同时说明第三个参数mode,用其说明该新文件的存取许可权限。
O_EXCL 如果同时指定了OCREAT,而文件已经存在,则返回-1
O_APPEND 每次写时都加到文件的尾端
O_TRUNC 属性去打开文件时,如果这个文件中本来是有内容的,而且为只读或只写成功打开,则将其长度截短为0
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
int main()
{
int fd;
fd =open("./file1",O_RDWR|O_CREAT|O_EXCL,0600);
if(fd==-1){
printf("file exists!!!");
}
return 0;
}
在文件中的内容后加上内容,不覆盖原内容:
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
int main()
{
int fd;
char *buf="I Love you the way you are!";
fd =open("./file1",O_RDWR|O_APPEND);
printf("open success:fd=%d\n",fd);
int n_write=write(fd,buf,strlen(buf));
if(n_write!=-1){
printf("write %d byte to file\n",n_write);
}
close(fd);
return 0;
}
将之前文件内容清空
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
int main()
{
int fd;
char *buf="test";
fd =open("./file1",O_RDWR|O_TRUNC);
printf("open success:fd=%d\n",fd);
int n_write=write(fd,buf,strlen(buf));
if(n_write!=-1){
printf("write %d byte to file\n",n_write);
}
close(fd);
return 0;
}
创建文件时带权限
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
int main()
{
int fd;
char *buf="test";
fd = creat("home/file1",S_IRWXU);//可读、写、执行
//fd = creat("home/file1",S_IRUSR)可读
//fd=creat("home/file1",S_IWUSR)可写
//fd=creat("home/file",S_IXUSR)可执行
return 0;
}