If you have ever used Linux or any other Unix-like operating system, you have probably come across the saying 'Everything is a file.' But what does that mean? Is everything in these systems actually a file? Well, that is not the case. To understand the saying, we will walk through various definitions that try to answer the question: What is a file?
What Is a File in the Real World
In the world we live in, a file is simply a container for documents. The document contains useful information, usually in the form of pages. There are four fundamental actions you can perform on a file in the real world:
- open
- read
- write
- close
The process of working with a file involves these four operations. When given a file, you first open it, then read through it by flipping through the pages of the file. If you have the right permissions, you can write to the file. When you are done, you can then close the file.
Computer files on storage devices
In computer systems, one way to define a file is as any piece of data stored on a storage device.
The same four fundamental operations that can be performed on real-world files can also be performed on computer files. The only difference is how the data is stored. Computer files are stored as streams of data.
They are called streams because instead of storing your file in one big location, the file is subdivided into smaller chunks. These chunks are similar to pages in a real-world file, and the process of streaming through those chunks is analogous to flipping through a file.
When you open a file on a computer, the operating system goes to your storage device and fetches the location of the file. Once its location has been fetched, you can either choose to read from the stream or write to the stream or perform both actions. When you are done with the file, you close it. These operations are exactly the same as the operations performed on files in the real world.
When working with files, the only thing that ever changes is the data source. Your file might be on a hard disk, CD-ROM, or flash drive, but you will still perform the same four fundamental operations, and its content is always streams.
Everything isn't a file rather everything is file like
The heading above is what the saying should have been, but it is a mouthful and isn't catchy. In Unix-like operating systems, everything is said to be a file because you can perform the same set of operations described for files stored on storage devices on other resources. These resources are commonly referred to as file-like.
You can open a particular file-like resource, read from it, write to it, and close it when you are done. The data from that resource is also streamed. The only thing that ever changes is the source of the data.
For instance, when you are typing in your terminal, you are actually writing to a resource called standard input. When data gets displayed to your terminal using the echo command, your operating system is writing to the standard output resource.
Another example of a file-like entity is a network connection to a server. When you make a connection to a server, you are opening a line of communication. You can send network requests to the server, which is equivalent to writing, and when the server responds, you are then reading. After the communication is over, you can then close the line of communication. The data is also in the form of a stream.
This same process applies to the majority of other resources in Unix-like operating systems, like when two processes are communicating; their means of communicating is file-like.
Reason why everything is a file
Seeing everything as a file is actually a clever design decision made by the creators of Unix. This allows the same set of APIs to be used across different tasks. When you open a file-like entity, it returns a file descriptor. A file descriptor is a unique integer that represents an open file. Standard input has the file descriptor of 0
, while standard output has the file descriptor of 1
. Several system calls in Unix work with file descriptors.
The example below uses the write system call to write Hello, world! to standard output.
#include <unistd.h>
int main() {
write(1, "Hello, world!\n", 14);
return 0;
}
The write system call can also be used to write to a file on disk.
#include <fcntl.h>
#include <unistd.h>
int main() {
// Get the file description
int fd = open("output.txt", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
// write to the file
write(fd, "Hello, World!\n", 14);
// close the file
close(fd);
return 0;
}
The program above opens a file called output.txt
. Then writes hello world to it. After that it closes the file using the close system call. As you can see both writing to standard output and writing to a file use the same function.
The code snippet below shows a C function that makes a request to a server. It does this by writing to the client socket. Which is file-like because it returns a file descriptor when created.
void send_http_request(int client_socket, const char *host, const char *path){
// Create the HTTP request
char request[MAX_BUFFER_SIZE];
snprintf(request, sizeof(request), "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", path, host);
// send the HTTP request to the server
write(client_socket, request, strlen(request));
}
The function below reads from the socket. The loop is used to receive the streams of data as they come.
void receive_http_response(int client_socket){
// Recieve and print the HTTP response from the server
char response[MAX_BUFFER_SIZE];
ssize_t bytes_received;
// Read response streams
while ((bytes_received = read(client_socket, response, sizeof(response) - 1)) > 0 ) {
// Add string termination
response[bytes_received] = '\0';
printf("%s", response);
}
}
So to reiterate on the question I asked earlier, what is a file? A file is any resource that streams it's data content. This content can be read from or written to. A lot resources on Unix-like Operating system follow this pattern and that is why everything is a file.
Top comments (0)