"Everything is a file" Explained
Tags: programming, learning, linux, computerscience
Published: 2023-12-08 09:52:51

If you have ever used Linux or any other [Unix-like operating system](https://en.wikipedia.org/wiki/Unix-like), 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

![Files in the real world](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/usnv8hv6kt2mlqi6hqv6.jpg)

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

![Computer files](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9fc44g06tj0cf1rzgjel.jpg)

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.

![File Streams](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yp9sal845op004nmpp4i.png)

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](https://en.wikipedia.org/wiki/Echo_(command)) 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](https://en.wikipedia.org/wiki/Process_(computing)) 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](https://en.wikipedia.org/wiki/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](https://en.wikipedia.org/wiki/System_call) in Unix work with file descriptors.


The example below uses the [write](https://en.wikipedia.org/wiki/Write_(system_call)) system call to write **Hello, world!** to standard output.

```C
#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.

```C
#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](https://en.wikipedia.org/wiki/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.

```C
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.

```C
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**.