C language programming in Linux: File Operations

Source: Internet
Author: User
1. File Creation and read/write
I suppose you already know all the functions for standard file operations (fopen, fread, fwrite, etc ). of course, don't worry if you don't know. the system-level file operations we discuss actually serve standard-level file operations.
When we need to open a file for read/write operations, we can use the system call function open. After the use is complete, we call another close function to close the operation.
# Include
# Include
# Include
# Include

Int open (const char * pathname, int flags );
Int open (const char * pathname, int flags, mode_t mode );

Int close (int fd );

The open function has two forms. here, pathname is the name of the file we want to open (including the path name, which is considered to be under the current path by default ). flags can be used to combine the following values or values.
O_rdonly: open the file in read-only mode.
O_wronly: open the file in write-only mode.
O_rdwr: open a file in read/write mode.
O_append: open the file in append mode.
O_creat: Creates a file.
O_exec: If o_creat is used and the file already exists, an error occurs.
O_noblock: open a file in non-blocking mode.
O_trunc: if the file already exists, delete the file content.
Only one of the first three labels can be used. if the o_create flag is used, we need to use the second form of open. specify the mode flag to indicate the object access permission. mode can be a combination of the following conditions.
-----------------------------------------------------------------
S_irusr users can read s_iwusr users can write
S_ixusr user can execute s_irwxu user can read and write execution
-----------------------------------------------------------------
S_irgrp group can read s_iwgrp group can write
S_ixgrp group can run s_irwxg group can read and write
-----------------------------------------------------------------
S_iroth others can read s_iwoth others can write
S_ixoth others can execute s_irwxo others can read and write
-----------------------------------------------------------------
S_isuid: Set the user execution ID s_isgid: Set the execution ID of the Group
-----------------------------------------------------------------
We can also use numbers to represent the symbols of each bit. Linux uses a total of five numbers to represent various permissions of the file.
00000. the first digit indicates setting the user ID. The second digit indicates setting the group ID, the third digit indicates the user's own permission, the fourth digit indicates the Group permission, and the last digit indicates the permissions of others.
Each number can be 1 (Execution permission), 2 (write permission), 4 (read permission), 0 (nothing), or the sum of these values.
For example, if you want to create a user read/write execution, the group does not have the permission to read the files executed by others. set the user ID. The available mode is -- 1 (set the user ID) 0 (the group is not set) 7 (1 + 2 + 4) 0 (no permission, use the default value) 5 (1 + 4) is 10705:
Open ("Temp", o_creat, 10705 );
If the file is successfully opened, open will return a file descriptor. We will be able to operate all operations on the file descriptor in the future.
After the operation is complete, we need to close the file. You only need to call close. FD is the file descriptor to be closed.
After the file is opened, we need to read and write the file. We can call the Read and Write Functions to read and write the file.
# Include

Ssize_t read (int fd, void * buffer, size_t count );
Ssize_t write (int fd, const void * buffer, size_t count );

FD is the file descriptor for reading and writing operations, and buffer is the memory address for writing or reading the file content. Count is the number of bytes to read and write.
For a Common File Read, read the Count byte from the specified file (FD) to the buffer (remember that we must provide a buffer that is large enough), and return the count.
If the read reads the end Of the file or is interrupted by a signal, the returned value is smaller than count. if it is returned due to a signal interruption and no data is returned, read returns-1 and errno is set to eintr. whenProgramWhen the end of the file is read, read returns 0.
Write writes the Count byte from the buffer to the file FD. The actual number of bytes written is returned when the operation is successful.
Next we will learn an instance which is used to copy files.

# Include
# Include
# Include
# Include
# Include
# Include
# Include

# Define buffer_size 1024

Int main (INT argc, char ** argv)
{

Int from_fd, to_fd;
Int bytes_read, bytes_write;
Char buffer [buffer_size];
Char * PTR;

If (argc! = 3)
{
Fprintf (stderr, "Usage: % s fromfile tofile \ n \ A", argv [0]);
Exit (1 );
}

/* Open the source file */

If (from_fd = open (argv [1], o_rdonly) =-1)
{
Fprintf (stderr, "Open % s error: % s \ n", argv [1], strerror (errno ));
Exit (1 );
}

/* Create the target file */

If (to_fd = open (argv [2], o_wronly | o_creat, s_irusr | s_iwusr) =-1)
{
Fprintf (stderr, "Open % s error: % s \ n", argv [2], strerror (errno ));
Exit (1 );
}

/* The followingCodeIs a classic copy file code */

While (bytes_read = read (from_fd, buffer, buffer_size ))
{
/* A fatal error occurred */
If (bytes_read =-1) & (errno! = Eintr) break;
Else if (bytes_read> 0)
{
PTR = buffer;
While (bytes_write = write (to_fd, PTR, bytes_read ))
{
/* A fatal error occurred */
If (bytes_write =-1) & (errno! = Eintr) break;
/* All read bytes have been written */
Else if (bytes_write = bytes_read) break;
/* Write only a part and continue writing */
Else if (bytes_write> 0)
{
PTR + = bytes_write;
Bytes_read-= bytes_write;
}
}
/* Fatal error during write */
If (bytes_write =-1) break;

}
}
Close (from_fd );
Close (to_fd );
Exit (0 );
}

2. File Attributes
The file has various attributes. Apart from the file permissions we know above, the file also has attributes such as creation time and size.
Sometimes we need to determine whether a file can perform certain operations (read, write, etc.). In this case, we can use the access function.
# Include

Int access (const char * pathname, int mode );

Pathname: indicates the file name and mode is the attribute to be judged. You can take the following values or their combinations.
R_ OK files can be read, w_ OK files can be written, x_ OK files can be executed, and f_ OK files exist. when the test is successful, the function returns 0. Otherwise, if a condition does not match,-1 is returned.
If we want to obtain other attributes of the file, we can use the stat or fstat function.
# Include
# Include

Int Stat (const char * file_name, struct stat * BUF );
Int fstat (INT filedes, struct stat * BUF );

Struct stat {
Dev_t st_dev;/* Device */
Ino_t st_ino;/* node */
Mode_t st_mode;/* mode */
Nlink_t st_nlink;/* hard connection */
Uid_t st_uid;/* User ID */
Gid_t st_gid;/* Group ID */
Dev_t st_rdev;/* device type */
Off_t st_off;/* Number of file bytes */
Unsigned long st_blksize;/* block size */
Unsigned long st_blocks;/* number of blocks */
Time_t st_atime;/* last access time */
Time_t st_mtime;/* last modification time */
Time_t st_ctime;/* last change time (attribute )*/
};

Stat is used to determine files that are not opened, while fstat is used to determine files that are opened. the most commonly used attribute is st_mode. through the attribute, we can determine whether a given file is a common file, a directory, a connection, and so on. you can use the following macros to determine.
S_islnk
(St_mode): whether it is a connection. s_isreg is a regular file. s_isdir is a directory, s_ischr is a character device.
S_isblk is a block device; s_isfifo is a FIFO file; s_issock is a socket file.
We will explain how to use these macros below.
3. Directory file operations
When we write a program, we sometimes need to get our current working path. The C library function provides getcwd to solve this problem.
# Include

Char * getcwd (char * buffer, size_t size );

We provide a buffer of size. getcwd will test our current path to the buffer. If the buffer is too small, the function will return-1 and an error number.
Linux provides a large number of directory operation functions. We will learn a few simple and common functions.
# Include
# Include
# Include
# Include
# Include

Int mkdir (const char * path, mode_t mode );
Dir * opendir (const char * path );
Struct dirent * readdir (dir * DIR );
Void rewinddir (dir * DIR );
Off_t telldir (dir * DIR );
Void seekdir (dir * Dir, off_t off );
Int closedir (dir * DIR );

Struct dirent {
Long d_ino;
Off_t d_off;
Unsigned short d_reclen;
Char d_name [name_max + 1];/* file name */

Mkdir
It is easy to create a directory. opendir opens a directory to prepare for future reading. readdir reads an Open Directory. rewinddir is used to re-read the Directory and learn
The same as the rewind function. closedir is to close a directory. telldir and seekdir are similar to ftee and fseek functions.
Below we develop a small program, which has a parameter. if this parameter is a file name, we will output the file size and the last modification time. If it is a directory, We will output the size and modification time of all files in this directory.

# Include
# Include
# Include
# Include
# Include
# Include
# Include

Static int get_file_size_time (const char * filename)
{
Struct stat statbuf;

If (STAT (filename, & statbuf) =-1)
{
Printf ("Get stat on % s error: % s \ n ",
Filename, strerror (errno ));
Return (-1 );
}

If (s_isdir (statbuf. st_mode) Return (1 );
If (s_isreg (statbuf. st_mode ))
Printf ("% s size: % LD bytes \ tmodified at % s ",
Filename, statbuf. st_size, ctime (& statbuf. st_mtime ));

Return (0 );
}

Int main (INT argc, char ** argv)
{
Dir * dirp;
Struct dirent * direntp;
Int stats;

If (argc! = 2)
{
Printf ("Usage: % s filename \ n \ A", argv [0]);
Exit (1 );
}

If (Stats = get_file_size_time (argv [1]) = 0) | (Stats =-1) Exit (1 );

If (dirp = opendir (argv [1]) = NULL)
{
Printf ("Open Directory % s error: % s \ n ",
Argv [1], strerror (errno ));
Exit (1 );
}

While (direntp = readdir (dirp ))! = NULL)
If (get_file_size_time (direntp-closedir (dirp );
Exit (1 );
}

4. MPs queue File
Linux provides many filtering and redirection programs, such as more cat
And so on. The redirection operators such as <>|< are also provided. Special files such as pipelines are used in these filtering and retargeting programs. You can create a pipeline by calling pipe.
# Include

Int pipe (INT Fildes [2]);

You can create an MPS Queue (Communication buffer) by calling pipe ). when the call is successful, we can access the file descriptor Fildes [0], Fildes [1]. fildes [0] is the file descriptor used for reading, while Fildes [1] is the file descriptor used for writing.
In actual use, we create a sub-process, write a process, and read it by a process.
For more information about Process Communication, see Process Communication.

# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Define buffer 255.

Int main (INT argc, char ** argv)
{
Char buffer [buffer + 1];
Int FD [2];

If (argc! = 2)
{
Fprintf (stderr, "Usage: % s string \ n \ A", argv [0]);
Exit (1 );
}

If (pipe (FD )! = 0)
{
Fprintf (stderr, "pipe error: % s \ n \ A", strerror (errno ));
Exit (1 );
}
If (Fork () = 0)
{
Close (FD [0]);
Printf ("child [% d] Write to pipe \ n \ A", getpid ());
Snprintf (buffer, buffer, "% s", argv [1]);
Write (FD [1], buffer, strlen (buffer ));
Printf ("child [% d] Quit \ n \ A", getpid ());
Exit (0 );
}
Else
{
Close (FD [1]);
Printf ("parent [% d] read from pipe \ n \ A", getpid ());
Memset (buffer, '\ 0', buffer + 1 );
Read (FD [0], buffer, buffer );
Printf ("parent [% d] Read: % s \ n", getpid (), buffer );
Exit (1 );
}
}

To implement the redirection operation, we need to call another function dup2.
# Include

Int dup2 (INT oldfd, int newfd );

Dup2 uses the oldfd file descriptor to replace the newfd file descriptor, and closes the newfd file descriptor. That is,
All operations directed to newfd are forwarded to oldfd. Here is an example to redirect the standard output to a file.

# Include
# Include
# Include
# Include
# Include
# Include
# Include

# Define buffer_size 1024

Int main (INT argc, char ** argv)
{
Int FD;
Char buffer [buffer_size];

If (argc! = 2)
{
Fprintf (stderr, "Usage: % s outfilename \ n \ A", argv [0]);
Exit (1 );
}

If (FD = open (argv [1], o_wronly | o_creat | o_trunc, s_irusr | s_iwusr) =-1)
{
Fprintf (stderr, "Open % s error: % s \ n \ A", argv [1], strerror (errno ));
Exit (1 );
}

If (dup2 (FD, stdout_fileno) =-1)
{
Fprintf (stderr, "Redirect standard out error: % s \ n \ A", strerror (errno ));
Exit (1 );
}

Fprintf (stderr, "now, please input string ");
Fprintf (stderr, "(to quit use Ctrl + d) \ n ");
While (1)
{
Fgets (buffer, buffer_size, stdin );
If (feof (stdin) break;
Write (stdout_fileno, buffer, strlen (buffer ));
}
Exit (0 );
}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.