Linux下如何编写C程序合并当前目录所有TXT文件并返回文件描述符
Merge All .txt Files in Current Directory & Return File Descriptor (Linux C)
Alright, let's walk through how to build this C program for Linux. The goal is to scan your current working directory, grab every .txt file, merge their contents into a single new file, and return that new file's file descriptor. Here's a complete, robust implementation plus explanations.
Full Working Code
#include <stdio.h> #include <dirent.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include <stdlib.h> #include <errno.h> #define OUTPUT_FILE "merged_result.txt" #define BUFFER_SIZE 4096 // Use a 4KB buffer for efficient I/O int merge_txt_files() { DIR *dir; struct dirent *entry; int output_fd, input_fd; ssize_t bytes_read; char buffer[BUFFER_SIZE]; // Open current directory dir = opendir("."); if (!dir) { perror("Failed to open current directory"); return -1; } // Create output file (overwrite if exists, set read/write permissions for owner, read for others) output_fd = open(OUTPUT_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (output_fd == -1) { perror("Failed to create output file"); closedir(dir); return -1; } // Iterate through directory entries while ((entry = readdir(dir)) != NULL) { // Skip the output file itself to avoid infinite loops/duplication if (strcmp(entry->d_name, OUTPUT_FILE) == 0) { continue; } // Check if the file ends with .txt size_t len = strlen(entry->d_name); if (len >= 4 && strcmp(entry->d_name + len - 4, ".txt") == 0) { // Open the input .txt file input_fd = open(entry->d_name, O_RDONLY); if (input_fd == -1) { fprintf(stderr, "Warning: Could not open %s - %s\n", entry->d_name, strerror(errno)); continue; // Skip this file and move to next } // Read from input file and write to output file while ((bytes_read = read(input_fd, buffer, BUFFER_SIZE)) > 0) { if (write(output_fd, buffer, bytes_read) != bytes_read) { perror("Failed to write to output file"); close(input_fd); close(output_fd); closedir(dir); return -1; } } if (bytes_read == -1) { perror("Failed to read input file"); close(input_fd); close(output_fd); closedir(dir); return -1; } // Close the input file after processing close(input_fd); } } // Clean up directory handle closedir(dir); // Return the file descriptor of the merged file return output_fd; } int main() { int fd = merge_txt_files(); if (fd != -1) { printf("Merged file created successfully. File descriptor: %d\n", fd); // Note: If you're done with the file, you should close it here // close(fd); } return fd == -1 ? EXIT_FAILURE : EXIT_SUCCESS; }
Key Explanations
1. Directory Traversal
- We use
opendir(".")to open the current working directory.readdir()iterates through each entry in the directory. - We skip the output file (
merged_result.txt) to prevent it from being included in the merge (which would cause duplicate content or infinite loops if we ran the program multiple times without deleting the output first). - To check for
.txtfiles, we verify the last 4 characters of the filename match.txt(we make sure the filename is at least 4 characters long first to avoid out-of-bounds access).
2. File I/O Handling
- The output file is created with
open()using flagsO_WRONLY(write-only),O_CREAT(create if it doesn't exist), andO_TRUNC(truncate to zero length if it does exist). The permission0644means the owner can read/write, others can read. - We use a 4KB buffer (
BUFFER_SIZE 4096) for reading/writing—this is more efficient than reading/writing byte-by-byte, as it reduces the number of system calls. - The
read()andwrite()loop ensures we handle partial reads/writes (common with large files), where not all data is transferred in a single call.
3. Error Handling
- Every system call (
opendir,open,read,write,closedir) has error checking. We useperror()orstrerror(errno)to print meaningful error messages. - If an error occurs mid-process, we clean up all open resources (close file descriptors, close the directory) before returning an error code (
-1).
Important Notes
- Avoid naming the output file with a
.txtextension: If you do, make sure to explicitly skip it (like we do in the code) to prevent it from being merged into itself. - Resource cleanup: Always close file descriptors and directory handles when you're done with them to avoid resource leaks. In the
main()function, we leave the file descriptor open (as per the requirement to return it), but you should close it once you're finished using it. - Permissions: The
0644permission is a safe default, but you can adjust it based on your needs (e.g.,0600if only the owner should have access). - Hidden files: The code will include hidden
.txtfiles (like.secret.txt) sincereaddir()returns all entries except.and... If you want to skip hidden files, add a check to skip entries starting with..
内容的提问来源于stack exchange,提问作者robin
相关产品推荐
相关产品推荐

