Concise file operation under Linux Linux

1 lseek function

Function: off_t lseek(int fd, off_t offset, int whence)

Header file: #include < unistd h> #include <sys/types. h>

Parameter: fd file descriptor

Offset offset, which can be positive or negative

The starting position of the where offset can be set in three ways

SEEK_SET	#Start position
          The file offset is set to offset bytes.
SEEK_CUR	#Cursor position
          The  file  offset  is  set  to its current location plus offset bytes.
SEEK_END	#File end location
          The file offset is set to the size  of  the  file  plus  offset bytes.

Return value: normal end, return the number of bytes from the beginning to the offset position; Returns - 1 if an error occurs

Special: when the offset value of the file exceeds its allowable value, the file will be expanded

Note: the read and write of the file use the same offset position

demo of the use of an lseek function:

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char** argv)
{
    int fd1;
    int flag,i=0;
    char s1[]="It's a lseek test\n";
    char c;
    fd1=open("lseek.txt",O_CREAT|O_RDWR,0664);
    if(fd1<0){
        perror("create file failed");
    }
    while((c=s1[i])!='\0'){
        write(fd1,&c,1);
        i++;
    }
    //The lseek() function of three insertion positions is written here
    //If the function is not inserted here, when the character is read again, it will be read from the end of the last write position
    //The result is nothing to read
    lseek(fd1,0,SEEK_SET);
    // lseek(fd1,-strlen(s1),SEEK_END);
    // lseek(fd1,-strlen(s1),SEEK_CUR);
    while((flag=read(fd1,&c,1))!=0){
        write(STDOUT_FILENO,&c,1);
    }
    close(fd1);
    return 0;
}

Other application scenarios:

(1) Use lseek to obtain the file size;

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
    int fd1;
    int length=0;
    fd1=open(argv[1],O_RDWR);
    if(fd1<0){
        perror("open file error");
    }
    length=lseek(fd1,0,SEEK_END);
    printf("The size of file is %d\n",length);
    close(fd1);
    return 0;
}

(2) Expand file size;

Use lseek tail to offset backward;

lseek(fd,N,SEEK_END); //N = number of offset bytes - 1;

write(fd,"\0",1);// If the file size changes, IO operation must be performed

od -tcx [file]

The truncate() function can also be used to expand the file size;

int ret=truncate("dict.cp",250);

2 incoming and outgoing parameters

Incoming parameters:

1. Pointer as function parameter;

2. It is usually modified by const keyword; (because it is an incoming parameter, use const to prevent the value from being tampered with)

3. The pointer points to the valid area and reads inside the function;

For example, src in char *strcpy(char *dest, const char *src)

Outgoing parameters:

1. Pointer as function parameter;

2. Before the function call, the space pointed to by the pointer may be meaningless, but it must be valid;

3. Write inside the function;

4. After the function call, it acts as the return value of the function;

For example, dest in char *strcpy(char *dest, const char *src)

Incoming and outgoing parameters:

1. Pointer as function parameter;

2. Before the function call, the space pointed to by the pointer is determined by the actual meaning;

3. Inside the function, read first and write later;

4. After the function call, it can be used as the return value of the function;

For example: char *strtok_r(char *str,const char *delim, char ** saveptr)

3 file system and file storage

Inode: use stat file to view the inode of the file

Inodes are essentially structures that store attribute information of files, such as permissions, types, sizes, times, users, disk block locations, etc. they are also called document attribute management structures. Most inode s are stored on disk

A small number of frequently used / recently used inode s will be cached in memory

dentry: Directory item, whose essence is still a structure. The important member variables are composed of two {file names; inode;...}, and the file content (data) is saved in the disk block;

Deleting a file is not to delete the file, but to overwrite the old file with a new file;

After the disk is formatted, the data can still be recovered, but the original file can be overwritten by pouring in the large video and rewriting the file;

4 stat function

**Function: int stat(const char path, struct stat buf)

Header file: #include < sys / types h>

​ #include <sys/stat.h>

​ #include <unistd.h>

Parameter: path file path

buf outgoing parameters,

Return value: 0 for success and - 1 for failure;

Function Description: these functions return information about a file, in the buffer pointed to by statbuf No permissions are required on the file itself, but—in the case of stat(), fstatat(), and lstat()—execute (search) permission is required on all of the directories in pathname that lead to the file.

      
        struct stat {
               dev_t     st_dev;         /* ID of device containing file */
               ino_t     st_ino;         /* Inode number */
               mode_t    st_mode;        /* File type and mode */
               nlink_t   st_nlink;       /* Number of hard links */
               uid_t     st_uid;         /* User ID of owner */
               gid_t     st_gid;         /* Group ID of owner */
               dev_t     st_rdev;        /* Device ID (if special file) */
               off_t     st_size;        /* Total size, in bytes */
               blksize_t st_blksize;     /* Block size for filesystem I/O */
               blkcnt_t  st_blocks;      /* Number of 512B blocks allocated */  /* Since Linux 2.6, the kernel supports nanosecond
                  precision for the following timestamp fields.
                  For the details before Linux 2.6, see NOTES. */struct timespec st_atim;  /* Time of last access */
           struct timespec st_mtim;  /* Time of last modification */
           struct timespec st_ctim;  /* Time of last status change */

       #define st_atime st_atim.tv_sec      /* Backward compatibility */
       #define st_mtime st_mtim.tv_sec
       #define st_ctime st_ctim.tv_sec
       };

Attribute: st_mode

Stat penetration: when using stat to view the soft link information of a file, the information found is the information of the source file rather than the soft link information. This phenomenon is called stat penetration.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
int main(int argc, char** argv)
{
    struct stat sbuf;
    int ret=stat(argv[1],&sbuf);
    if(ret==-1){
        perror("open file error!");
        exit(-1);
    }
    printf("The size of file is %ld\n",sbuf.st_size);
    if(S_ISREG(sbuf.st_mode)){
        printf("this is a regular file!\n");
    }
    else if(S_ISDIR(sbuf.st_mode)){
        printf("this is dir\n");
    }
    else if(S_ISLNK(sbuf.st_mode)){
        printf("this is soft link\n");
    }
    else{
        printf("the file is unknown");
    }
    return 0;   
}
-rwxrwxr-x 1 daniel daniel   16792 5 November 3:41 block
lrwxrwxrwx 1 daniel daniel       7 5 November 14:09 block1 -> block.c
daniel@daniel-Vostro-5471:~/file/OS/test/IO_test$ ./stat.out block1
The size of file is 217
this is a regular file!#Displays information about the source file of the soft link

Stat function and lstat function are basically the same, except that stat will penetrate symbolic connections, while lstat function will not penetrate symbolic connections;

Modify the above stat function to lstat function, and it is found that the symbolic connection is no longer penetrated.

daniel@daniel-Vostro-5471:~/file/OS/test/IO_test$ ./stat.out block1
The size of file is 7
this is soft link
       S_IFMT     0170000   bit mask for the file type bit field
       S_IFSOCK   0140000   socket
       S_IFLNK    0120000   symbolic link
       S_IFREG    0100000   regular file
       S_IFBLK    0060000   block device
       S_IFDIR    0040000   directory
       S_IFCHR    0020000   character device
       S_IFIFO    0010000   FIFO

   Thus, to test for a regular file (for example), one could write:

       stat(pathname, &sb);
       if ((sb.st_mode & S_IFMT) == S_IFREG) {
           /* Handle regular file */
       }

Use stat.st_ The help of mode to judge the file type is located at man 7 inode

5 other simple functions

acess chmod truncate

*Function: int access(const char pathname,int mode);

Header file: #include < fcntl h> #include <unistd. h>

Function:

   The mode specifies the accessibility check(s) to be performed, and is  either the value F_OK, or a mask consisting of the bitwise OR of one or more of R_OK, W_OK, and X_OK.  F_OK tests for the existence of the file.  R_OK, W_OK,  and  X_OK  test whether the file exists and grants read, write, and execute permissions, respectively.

Parameter: pathname fill in the path of the detection file

mode add permissions to detect files

Return value:

On success (all requested permissions granted, or mode  is  F_OK  and  the file  exists), zero is returned.  On error (at least one bit in mode asked   for a permission that is denied, or mode is F_OK and the file does not exist,  or  some other error occurred), -1 is returned, and errno is set ap     propriately.

demo:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char** argv)
{
    int ret1=access(argv[1],F_OK);
    if(ret1==-1){
        perror("can't find the file\n");
    }
    else{
        printf("The file is exit!\n");
    }
    int ret2=access(argv[1],R_OK);
    if(ret2==-1){
        perror("can't read the file!\n");
    }
    else{
        printf("you can read the file\n");
    }
    return 0;
}

*Function: int chmod(const char pathname,mode_t mode)

Header file: #include < sys / stat.h >

Function: change file properties

Parameters: pathname is the address of the file, and mode is a series of macro definitions representing file attributes. For details, see the help document man 2 chmod

Return value: on success, zero is returned On error, -1 is returned, and errno is set appropriately.

*Function: int truncate(const char path,off_t length)

​ int ftruncate(int fd, off_t length)

Header file: #include < unistd h> #include<sys/types. h>

Function:

   The  truncate()  and ftruncate() functions cause the regular file named by path or referenced by fd to be truncated to a  size  of  precisely  length      bytes. If  the file previously was larger than this size, the extra data is lost.
   If the file previously was shorter, it is extended, and the extended  part reads as null bytes ('\0').
   The file offset is not changed. If  the size changed, then the st_ctime and st_mtime fields (respectively, time of last status change and time of last  modification;  see  inode(7)) for  the  file are updated, and the set-user-ID and set-group-ID mode bits may be cleared.
   With ftruncate(), the file must be open for writing; with truncate(),  the file must be writable.

Parameter: path file path fd file descriptor length truncated bytes

Return value:

0 is returned for success and - 1 is returned for failure;

demo:

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
int main(int argc, char** argv)
{
    int ret=truncate(argv[1],10);
    if(ret==-1){
        perror("can't truncate the file!\n");
    }
    else{
        printf("truncate the file successfully!\n");
    }
    return 0;
}

6 link/ulink / implicit recycling

**Function: int link(const char oldpath, const char newpath);

Header file: #include < unistd h>

Function: create hard connection

The dentry of the previous file storage is a structure composed of file name and inode. The files created by hard connection have different file names and inodes, that is, point to the same area on the disk. If you modify one file, the other will also be modified

Parameters: oldpath old file path newpath new file path

Return value: success, return 0, failure, return - 1

*Function: int unlink(const char pathname)

Header file: #include < unistd h>

Function: delete the directory entry of the file. Deleting files in linux is a continuous process_ Link minus 1 until st_link is 0. Files without directory corresponding entries will be released by the operating system.

 unlink()  deletes  a  name from the filesystem.  If that name was the last link to a file and no processes have the file open, the  file  is  deleted  and the space it was using is made available for reuse.
  If  the  name was the last link to a file but any processes still have the file open, the file will remain in existence until the last file  descrip     tor referring to it is closed.
  If the name referred to a symbolic link, the link is removed.If  the name referred to a socket, FIFO, or device, the name for it is removed but processes which have the object open may continue to use it.

Parameter: pathname file path

Return value: success, return 0, failure, return - 1

demo for realizing mv function in shell:

#include <unistd.h>
#include <stdio.h>
int main (int argc, char** argv){
    if(argc!=3){
        printf("the num of argv is wrong!\n");
    }
    int ret=link(argv[1],argv[2]);
    if(ret==-1){
        perror("move error!\n");
    }
    else{
        int ret2=unlink(argv[1]);
        if (ret2==-1){
            perror("delete the oldfile error!\n");
        }
    }
    return 0;
}

The feature of the unlink function is that when the file is cleared, the number of hard connections reaches 0, and there is no dentry corresponding to it, but the file will not be released immediately. The system will pick the time to release the file until all processes that open the file close the file. A demo code:

//Create a temp temporary file and delete it at the end of the program
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
    int fd;
    int ret;
    char* str1="this is the test1\n";
    char* str2="this is the test2\n";
    fd=open("temp.txt",O_RDWR|O_CREAT,0664);
    //>>1
    if(fd==-1){
        perror("can't create the file!");
        exit(-1);
    }
    ret=write(fd,str1,strlen(str1));
    if(ret==-1){
        perror("write failed!");
        exit(-1);
    }
    printf("write test1 successfully!\n");
    ret=write(fd,str2,strlen(str2));
        if(ret==-1){
        perror("write failed!");
        exit(-1);
    }
    printf("write test2 successfully!press enter to continue!\n");
    //Use getchar() to receive a carriage return. When the carriage return is not pressed, temp Txt file exists
    //When enter is pressed, the unlink function is called, and the process receives, temp Txt deleted
    getchar();
    close(fd);
    //Move the next sentence one place, and you can still write without reporting an error
    ret=unlink("temp.txt");
    if(ret==-1){
        perror("unlink the file failed!\n");
        exit(-1);
    }
    return 0;
}

Implicit recycling: when the process ends running, all open files of the process will be closed and the requested memory space will be released. This feature of the system is called implicit recycling of system resources;

7 file directory and rwx permission difference

readlink softlink can view the contents of the soft link

daniel@daniel-Vostro-5471:~/file/OS/test/IO_test$ readlink 1
/home/daniel/file/OS/test/IO_test/1.txt

int rename(const char* oldpath, const char* newpath)

When renaming a file, 0 is returned for success and - 1 is returned for failure

Keywords: C Linux Operation & Maintenance

Added by StefanRSA on Thu, 20 Jan 2022 00:55:23 +0200