Loading...
advfiles

Advanced File Handling in C

1. Introduction

Advanced file handling techniques in C allow greater control and flexibility, enabling efficient data manipulation, random access, and binary file operations. These methods are crucial for handling large datasets, implementing databases, and managing complex file structures.


2. Random Access in Files

Why Random Access?

  • Allows reading or writing at any position in the file without processing the entire content sequentially.
  • Useful for large files where specific data needs to be accessed directly.

Functions Used:

FunctionDescription
fseekMoves the file pointer to a specific position.
ftellReturns the current position of the file pointer.
rewindResets the file pointer to the beginning.

Example: Using fseek and ftell

#include <stdio.h>

int main() {
    FILE *fp = fopen("example.txt", "r");
    if (fp == NULL) {
        printf("Error opening file.\n");
        return 1;
    }

    fseek(fp, 10, SEEK_SET); // Move file pointer 10 bytes from the start
    printf("File pointer position: %ld\n", ftell(fp));

    char ch = fgetc(fp); // Read the character at the new position
    printf("Character at position 10: %c\n", ch);

    rewind(fp); // Reset file pointer to the beginning
    printf("File pointer reset to: %ld\n", ftell(fp));

    fclose(fp);
    return 0;
}

3. Working with Binary Files

Binary File Operations

Binary files store data in raw format (0s and 1s). Unlike text files, they are not human-readable but are more compact and faster to read/write.

Writing to a Binary File:

#include <stdio.h>

struct Data {
    int id;
    char name[20];
    float marks;
};

int main() {
    struct Data d = {1, "Alice", 95.5};
    FILE *fp = fopen("data.bin", "wb");

    if (fp == NULL) {
        printf("Error opening file.\n");
        return 1;
    }

    fwrite(&d, sizeof(d), 1, fp);
    fclose(fp);
    return 0;
}

Reading from a Binary File:

#include <stdio.h>

struct Data {
    int id;
    char name[20];
    float marks;
};

int main() {
    struct Data d;
    FILE *fp = fopen("data.bin", "rb");

    if (fp == NULL) {
        printf("Error opening file.\n");
        return 1;
    }

    fread(&d, sizeof(d), 1, fp);
    printf("ID: %d, Name: %s, Marks: %.2f\n", d.id, d.name, d.marks);

    fclose(fp);
    return 0;
}

4. Appending Data to Files

Use the a or a+ mode to append data to the end of a file without overwriting existing content.

Example:

FILE *fp = fopen("example.txt", "a");
if (fp != NULL) {
    fputs("This is appended text.\n", fp);
    fclose(fp);
}

5. Error Handling in File Operations

Common Functions for Error Handling:

FunctionDescription
ferrorChecks for errors in file operations.
perrorPrints a descriptive error message.
clearerrResets the error and end-of-file indicators.

Example: Using ferror

FILE *fp = fopen("example.txt", "r");
if (fp == NULL) {
    perror("Error opening file");
    return 1;
}

char ch = fgetc(fp);
if (ferror(fp)) {
    printf("Error reading file.\n");
}

clearerr(fp); // Reset the error indicator
fclose(fp);

6. File Locking

File locking ensures that multiple processes or threads do not interfere with file operations.

Example: Implementing File Locking (POSIX System)

#include <stdio.h>
#include <fcntl.h>

int main() {
    FILE *fp = fopen("example.txt", "r+");
    if (fp == NULL) {
        perror("Error opening file");
        return 1;
    }

    int fd = fileno(fp); // Get file descriptor

    // Lock file
    if (flock(fd, LOCK_EX) == 0) {
        printf("File locked successfully.\n");
        // Perform operations on the file
        flock(fd, LOCK_UN); // Unlock file
    } else {
        perror("Error locking file");
    }

    fclose(fp);
    return 0;
}

7. Removing and Renaming Files

Removing a File

if (remove("file.txt") == 0) {
    printf("File deleted successfully.\n");
} else {
    printf("Error deleting file.\n");
}

Renaming a File

if (rename("oldname.txt", "newname.txt") == 0) {
    printf("File renamed successfully.\n");
} else {
    printf("Error renaming file.\n");
}

8. Working with Temporary Files

Using tmpfile

Creates a temporary file that is automatically deleted when closed.

FILE *fp = tmpfile();
if (fp != NULL) {
    fputs("Temporary data\n", fp);
    fclose(fp); // File is deleted
}

9. Example: Searching and Replacing in a File

#include <stdio.h>
#include <string.h>

int main() {
    FILE *fp = fopen("example.txt", "r+");
    if (fp == NULL) {
        printf("Error opening file.\n");
        return 1;
    }

    char buffer[100];
    char temp[100];
    FILE *temp_fp = fopen("temp.txt", "w");

    while (fgets(buffer, sizeof(buffer), fp)) {
        if (strstr(buffer, "old_word")) {
            strcpy(temp, buffer);
            char *pos = strstr(temp, "old_word");
            strncpy(pos, "new_word", 8); // Replace "old_word" with "new_word"
            fputs(temp, temp_fp);
        } else {
            fputs(buffer, temp_fp);
        }
    }

    fclose(fp);
    fclose(temp_fp);
    remove("example.txt");
    rename("temp.txt", "example.txt");

    printf("Search and replace completed.\n");
    return 0;
}

10. Applications of Advanced File Handling

  1. Database Management: Efficient storage and retrieval of data.
  2. Log Systems: Maintaining log files for debugging and monitoring.
  3. File Compression: Manipulating binary data for compression.
  4. Multithreading: Handling files in a synchronized way