Section 5: File Operations
In this section, we will dive into file operations, which will be helpful for your work on the caching I/O project.
You can find the code for this section here.
Discussion Activity: Describing (File) Descriptors
DISCUSSION A. What are file descriptors? How does the operating system use file descriptors to represent files on disk?
DISCUSSION B. What operations can you perform on file descriptors? What are the system calls that perform these operations?
Question 1: The Writing's on the Wall
In this portion of the section, you will examine a series of short programs that involve writing to files. Each file contains the same text, "0123456789... This file is 55 characters (bytes) long!\n"
. For each of the programs, identify:
- How will the opened file change, if at all, as a result of running the above program?
- What output, if any, will be printed?
We encourage you to run the code in question number # by running make run-#
. This will also display the file before and after the program runs. For example, make run-1a
will run the code for question 1A.
QUESTION 1A. Consider the following C code:
int main() {
int fd = open("files/file1a.txt", O_RDWR);
// Edit the file contents
fd[0] = '1';
fd[1] = " byte was written!\n";
close(fd);
return 0;
}
The contents of file1a.txt
is "0123456789... This file is 55 characters (bytes) long!\n"
.
- How will
file1a.txt
change as a result of running the code? - What output, if any, will running the code produce?
QUESTION 1B. Consider the following C code:
int main() {
int fd = open("files/file1b.txt", O_RDWR);
// Determine how long the file is
struct stat stats;
fstat(fd, &stats);
printf("The file is %ld bytes long.\n", stats.st_size);
// Write data to end of file
char data[] = "This is 26 bytes of data.\n";
lseek(fd, 0, SEEK_END);
write(fd, data, strlen(data));
// Determine how long the file is now
fstat(fd, &stats);
printf("The file is now %ld bytes long.\n", stats.st_size);
close(fd);
return 0;
}
The contents of file1b.txt
is "0123456789... This file is 55 characters (bytes) long!\n"
.
- How will
file1b.txt
change as a result of running the code? - What output, if any, will running the code produce?
QUESTION 1C. Consider the following C code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main() {
int fd = open("files/file1c.txt", O_RDWR | O_APPEND);
// Write data to the file
char data[] = "8 bytes\n";
write(fd, data, 8);
// Read data from the same location
lseek(fd, -15, SEEK_END);
char buf[16];
memset(buf, '\0', 16);
int bytes_read = read(fd, buf, 15);
buf[bytes_read] = '\0';
// Print each character individually in case we have null bytes
printf("The data read was: ");
for (int i = 0; i < 16; i++) {
printf("%c", buf[i]);
}
printf(". It is %d bytes.\n", bytes_read);
close(fd);
return 0;
}
The contents of file1c.txt
is "0123456789... This file is 55 characters (bytes) long!\n"
.
- How will
file1c.txt
change as a result of running the code? - What output will running the code produce?
Question 2: Not All Who Seek are Lost
In this portion of the section, you will examine a series of short programs that involve seeking to files. Each file contains the same text, "0123456789... This file is 55 characters (bytes) long!\n"
. For each of the programs, identify:
- How will the opened file change, if at all, as a result of running the above program?
- What output, if any, will be printed?
QUESTION 2A. Consider the following C code:
int main() {
int fd = open("files/file2a.txt", O_RDWR);
// Seek to beyond end of file
lseek(fd, 128, SEEK_SET);
// Read data from file
char buf[16];
memset(buf, '\0', 16);
int bytes_read = read(fd, buf, 15);
buf[bytes_read] = '\0';
// Print each character individually in case we have null bytes
printf("The data read was: ");
for (int i = 0; i < 16; i++) {
printf("%c", buf[i]);
}
printf(". It is %d bytes.\n", bytes_read);
close(fd);
return 0;
}
The contents of file2a.txt
is "0123456789... This file is 55 characters (bytes) long!\n"
.
- How will
file2a.txt
change as a result of running the code? - What output, if any, will running the code in produce?
QUESTION 2B. Consider the following C code:
int main() {
int fd = open("files/file2b.txt", O_RDWR);
// Seek to beyond end of file
lseek(fd, 128, SEEK_SET);
// Write data to file
char data[] = "This is 18 bytes!\n";
write(fd, data, 18);
close(fd);
return 0;
}
The contents of file2b.txt
is "0123456789... This file is 55 characters (bytes) long!\n"
.
- How will
file2b.txt
change as a result of running the code?