File Operations: open, read, write, close, lseek
Understanding how Linux manages files at a low level is crucial for any systems programmer. In Linux, when you interact with files using system calls, you work with file descriptors. A file descriptor is a non-negative integer that uniquely identifies an open file within a process. The most fundamental system calls for file operations are open, read, write, close, and lseek. Each plays a specific role:
open: opens a file and returns a file descriptor;read: reads data from a file descriptor into a buffer;write: writes data from a buffer to a file descriptor;close: closes an open file descriptor, releasing resources;lseek: repositions the offset of the file descriptor for random access.
These calls provide the foundation for all file manipulation in Linux, allowing you to perform tasks such as copying files, reading logs, or updating configuration files directly from C programs.
file_ops_example.c
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <errno.h> #define BUFFER_SIZE 128 int main() { int src_fd, dest_fd; ssize_t bytes_read, bytes_written; char buffer[BUFFER_SIZE]; // Open source file for reading src_fd = open("input.txt", O_RDONLY); if (src_fd == -1) { perror("open source"); return 1; } // Open destination file for writing (create if doesn't exist, truncate if does) dest_fd = open("output.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644); if (dest_fd == -1) { perror("open destination"); close(src_fd); return 1; } // Read from source and write to destination while ((bytes_read = read(src_fd, buffer, BUFFER_SIZE)) > 0) { bytes_written = write(dest_fd, buffer, bytes_read); if (bytes_written != bytes_read) { perror("write"); close(src_fd); close(dest_fd); return 1; } } if (bytes_read == -1) { perror("read"); } // Use lseek to move to the beginning of the destination file if (lseek(dest_fd, 0, SEEK_SET) == -1) { perror("lseek"); } else { // Read first few bytes from destination file as a check bytes_read = read(dest_fd, buffer, 16); if (bytes_read > 0) { buffer[bytes_read] = '\0'; printf("First 16 bytes of output.txt: %s\n", buffer); } } // Close both files close(src_fd); close(dest_fd); return 0; }
This program demonstrates how file descriptors are managed and manipulated using system calls. When you call open, the kernel returns a file descriptor that you use for subsequent operations. Error handling is essential: after each system call, the return value is checked, and if an error occurs (such as failing to open a file), the program prints an error message using perror and exits or cleans up as needed. The lseek system call is used here to reposition the file offset to the start of the destination file (SEEK_SET), enabling random access. This allows the program to read from any position within the file, not just sequentially, which is useful for scenarios like updating specific records or skipping headers.
¡Gracias por tus comentarios!
Pregunte a AI
Pregunte a AI
Pregunte lo que quiera o pruebe una de las preguntas sugeridas para comenzar nuestra charla
Genial!
Completion tasa mejorada a 7.69
File Operations: open, read, write, close, lseek
Desliza para mostrar el menú
Understanding how Linux manages files at a low level is crucial for any systems programmer. In Linux, when you interact with files using system calls, you work with file descriptors. A file descriptor is a non-negative integer that uniquely identifies an open file within a process. The most fundamental system calls for file operations are open, read, write, close, and lseek. Each plays a specific role:
open: opens a file and returns a file descriptor;read: reads data from a file descriptor into a buffer;write: writes data from a buffer to a file descriptor;close: closes an open file descriptor, releasing resources;lseek: repositions the offset of the file descriptor for random access.
These calls provide the foundation for all file manipulation in Linux, allowing you to perform tasks such as copying files, reading logs, or updating configuration files directly from C programs.
file_ops_example.c
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <errno.h> #define BUFFER_SIZE 128 int main() { int src_fd, dest_fd; ssize_t bytes_read, bytes_written; char buffer[BUFFER_SIZE]; // Open source file for reading src_fd = open("input.txt", O_RDONLY); if (src_fd == -1) { perror("open source"); return 1; } // Open destination file for writing (create if doesn't exist, truncate if does) dest_fd = open("output.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644); if (dest_fd == -1) { perror("open destination"); close(src_fd); return 1; } // Read from source and write to destination while ((bytes_read = read(src_fd, buffer, BUFFER_SIZE)) > 0) { bytes_written = write(dest_fd, buffer, bytes_read); if (bytes_written != bytes_read) { perror("write"); close(src_fd); close(dest_fd); return 1; } } if (bytes_read == -1) { perror("read"); } // Use lseek to move to the beginning of the destination file if (lseek(dest_fd, 0, SEEK_SET) == -1) { perror("lseek"); } else { // Read first few bytes from destination file as a check bytes_read = read(dest_fd, buffer, 16); if (bytes_read > 0) { buffer[bytes_read] = '\0'; printf("First 16 bytes of output.txt: %s\n", buffer); } } // Close both files close(src_fd); close(dest_fd); return 0; }
This program demonstrates how file descriptors are managed and manipulated using system calls. When you call open, the kernel returns a file descriptor that you use for subsequent operations. Error handling is essential: after each system call, the return value is checked, and if an error occurs (such as failing to open a file), the program prints an error message using perror and exits or cleans up as needed. The lseek system call is used here to reposition the file offset to the start of the destination file (SEEK_SET), enabling random access. This allows the program to read from any position within the file, not just sequentially, which is useful for scenarios like updating specific records or skipping headers.
¡Gracias por tus comentarios!