How to Open and Read a File in C on Linux
Important Terminology
What is the File Descriptor?
File descriptor is integer that uniquely identifies an open file of the procedure.
File Descriptor tabular array: File descriptor table is the collection of integer array indices that are file descriptors in which elements are pointers to file table entries. One unique file descriptors tabular array is provided in operating system for each process.
File Table Entry: File table entries is a construction In-memory surrogate for an open file, which is created when procedure request to opens file and these entries maintains file position.
Standard File Descriptors: When any process starts, then that process file descriptors table's fd(file descriptor) 0, 1, 2 open automatically, (By default) each of these 3 fd references file tabular array entry for a file named /dev/tty
/dev/tty: In-memory surrogate for the terminal
Final: Combination keyboard/video screen
Read from stdin => read from fd 0 : Whenever we write any character from keyboard, it read from stdin through fd 0 and relieve to file named /dev/tty.
Write to stdout => write to fd 1 : Whenever we run into whatever output to the video screen, it's from the file named /dev/tty and written to stdout in screen through fd i.
Write to stderr => write to fd 2 : We see any fault to the video screen, it is also from that file write to stderr in screen through fd 2.
I/O Arrangement calls
Basically there are full 5 types of I/O system calls:
1. Create: Used to Create a new empty file.
Syntax in C language: int create(char *filename, mode_t fashion)
Parameter:
- filename : name of the file which yous want to create
- way : indicates permissions of new file.
Returns:
- return get-go unused file descriptor (generally iii when offset create employ in process because 0, 1, 2 fd are reserved)
- return -1 when error
How it piece of work in OS
- Create new empty file on disk
- Create file table entry
- Prepare first unused file descriptor to point to file table entry
- Return file descriptor used, -i upon failure
2. open: Used to Open the file for reading, writing or both.
Syntax in C linguistic communication #include<sys/types.h> #include<sys/stat.h> #include <fcntl.h> int open (const char* Path, int flags [, int way ]);
Parameters
- Path: path to file which you want to employ
- use accented path begin with "/", when you are not work in same directory of file.
- Use relative path which is simply file proper noun with extension, when you are work in aforementioned directory of file.
- flags : How you like to utilize
- O_RDONLY: read only, O_WRONLY: write just, O_RDWR: read and write, O_CREAT: create file if information technology doesn't exist, O_EXCL: preclude creation if it already exists
How information technology works in OS
- Discover the existing file on disk
- Create file table entry
- Set first unused file descriptor to point to file table entry
- Return file descriptor used, -1 upon failure
C
#include<stdio.h>
#include<fcntl.h>
#include<errno.h>
extern
int
errno
;
int
principal()
{
int
fd = open(
"foo.txt"
, O_RDONLY | O_CREAT);
printf
(
"fd = %d/n"
, fd);
if
(fd ==-1)
{
printf
(
"Error Number % d\due north"
,
errno
);
perror
(
"Program"
);
}
return
0;
}
Output:
fd = 3
3. close: Tells the operating organization you are done with a file descriptor and Close the file which pointed by fd.
Syntax in C language #include <fcntl.h> int shut(int fd);
Parameter:
- fd :file descriptor
Render:
- 0 on success.
- -one on error.
How it works in the OS
- Destroy file tabular array entry referenced by element fd of file descriptor table
– As long as no other process is pointing to it! - Set element fd of file descriptor table to Naught
C
#include<stdio.h>
#include <fcntl.h>
int
main()
{
int
fd1 = open(
"foo.txt"
, O_RDONLY);
if
(fd1 < 0)
{
perror
(
"c1"
);
exit
(ane);
}
printf
(
"opened the fd = % d\n"
, fd1);
if
(close(fd1) < 0)
{
perror
(
"c1"
);
exit
(i);
}
printf
(
"airtight the fd.\n"
);
}
Output:
opened the fd = 3 closed the fd.
C
#include<stdio.h>
#include<fcntl.h>
int
main()
{
int
fd1 = open(
"foo.txt"
, O_RDONLY, 0);
shut(fd1);
int
fd2 = open up(
"baz.txt"
, O_RDONLY, 0);
printf
(
"fd2 = % d\north"
, fd2);
exit
(0);
}
Output:
fd2 = 3
Here, In this code kickoff open() returns 3 because when main process created, and then fd 0, i, 2 are already taken by stdin, stdout and stderr. So showtime unused file descriptor is iii in file descriptor tabular array. Later on that in close() system phone call is free it this iii file descriptor and then after set 3 file descriptor every bit nothing. And so when we called 2nd open up(), so first unused fd is also three. Then, output of this programme is 3.
4. read: From the file indicated by the file descriptor fd, the read() function reads cnt bytes of input into the retentiveness area indicated by buf. A successful read() updates the admission fourth dimension for the file.
Syntax in C linguistic communication size_t read (int fd, void* buf, size_t cnt);
Parameters:
- fd: file descriptor
- buf: buffer to read data from
- cnt: length of buffer
Returns: How many bytes were really read
- return Number of bytes read on success
- return 0 on reaching end of file
- return -1 on error
- return -1 on signal interrupt
Important points
- buf needs to betoken to a valid memory location with length non smaller than the specified size considering of overflow.
- fd should exist a valid file descriptor returned from open() to perform read operation considering if fd is NULL then read should generate error.
- cnt is the requested number of bytes read, while the return value is the actual number of bytes read. Also, some times read arrangement phone call should read less bytes than cnt.
C
#include<stdio.h>
#include <fcntl.h>
int
main()
{
int
fd, sz;
char
*c = (
char
*)
calloc
(100,
sizeof
(
char
));
fd = open(
"foo.txt"
, O_RDONLY);
if
(fd < 0) {
perror
(
"r1"
);
exit
(1); }
sz = read(fd, c, 10);
printf
(
"called read(% d, c, 10). returned that"
" %d bytes were read.\n"
, fd, sz);
c[sz] =
'\0'
;
printf
(
"Those bytes are as follows: % southward\n"
, c);
}
Output:
called read(iii, c, ten). returned that 10 bytes were read. Those bytes are every bit follows: 0 0 0 foo.
Suppose that foobar.txt consists of the vi ASCII characters "foobar". Then what is the output of the following program?
C
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>
int
principal()
{
char
c;
int
fd1 = open up(
"sample.txt"
, O_RDONLY, 0);
int
fd2 = open up(
"sample.txt"
, O_RDONLY, 0);
read(fd1, &c, 1);
read(fd2, &c, i);
printf
(
"c = %c\north"
, c);
leave
(0);
}
Output:
c = f
The descriptors fd1 and fd2 each have their own open file tabular array entry, so each descriptor has its own file position for foobar.txt . Thus, the read from fd2 reads the start byte of foobar.txt , and the output is c = f, not c = o.
five. write: Writes cnt bytes from buf to the file or socket associated with fd. cnt should not be greater than INT_MAX (defined in the limits.h header file). If cnt is zero, write() simply returns 0 without attempting whatever other action.
#include <fcntl.h> size_t write (int fd, void* buf, size_t cnt);
Parameters:
- fd: file descriptor
- buf: buffer to write data to
- cnt: length of buffer
Returns: How many bytes were really written
- render Number of bytes written on success
- render 0 on reaching finish of file
- return -1 on error
- return -1 on indicate interrupt
Of import points
- The file needs to be opened for write operations
- buf needs to be at least equally long as specified past cnt because if buf size less than the cnt so buf will lead to the overflow condition.
- cnt is the requested number of bytes to write, while the render value is the actual number of bytes written. This happens when fd take a less number of bytes to write than cnt.
- If write() is interrupted by a signal, the effect is 1 of the post-obit:
-If write() has non written any data still, information technology returns -ane and sets errno to EINTR.
-If write() has successfully written some data, it returns the number of bytes information technology wrote earlier information technology was interrupted.
C
#include<stdio.h>
#include <fcntl.h>
master()
{
int
sz;
int
fd = open up(
"foo.txt"
, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if
(fd < 0)
{
perror
(
"r1"
);
exit
(ane);
}
sz = write(fd,
"hello geeks\north"
,
strlen
(
"how-do-you-do geeks\due north"
));
printf
(
"called write(% d, \"hello geeks\\n\", %d)."
" It returned %d\due north"
, fd,
strlen
(
"hello geeks\n"
), sz);
close(fd);
}
Output:
called write(3, "hello geeks\northward", 12). it returned eleven
Hither, when you run into in the file foo.txt later running the code, you go a "how-do-you-do geeks". If foo.txt file already have some content in information technology so write system call overwrite the content and all previous content are deleted and only "hello geeks" content will have in the file.
Impress "hi globe" from the program without utilise whatever printf or cout role.
C
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
int
principal (
void
)
{
int
fd[2];
char
buf1[12] =
"hello earth"
;
char
buf2[12];
fd[0] = open(
"foobar.txt"
, O_RDWR);
fd[one] = open(
"foobar.txt"
, O_RDWR);
write(fd[0], buf1,
strlen
(buf1));
write(one, buf2, read(fd[1], buf2, 12));
shut(fd[0]);
shut(fd[1]);
return
0;
}
Output:
hello earth
In this code, buf1 assortment'due south string "hello world" is offset write in to stdin fd[0] then later that this string write into stdin to buf2 array. After that write into buf2 array to the stdout and print output " hi world ".
This article is contributed past Kadam Patel. If you similar GeeksforGeeks and would like to contribute, you can too write an article using write.geeksforgeeks.org or mail your article to review-squad@geeksforgeeks.org. See your article appearing on the GeeksforGeeks principal page and help other Geeks.
Please write comments if you notice anything wrong, or you want to share more information nigh the topic discussed above.
Source: https://www.geeksforgeeks.org/input-output-system-calls-c-create-open-close-read-write/
0 Response to "How to Open and Read a File in C on Linux"
Post a Comment