Linux下对文件的读取

128 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

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;
}