面对read_header函数中创建的文件中的问题

时间:2012-03-12 14:50:51

标签: c file

我要从目录创建一个带有Header(元数据)的文件,为了维护文件列表,我正在创建包含文件名的自定义头, 文件和文件总数。

我遇到了一些问题,并从堆栈溢出和完整的元数据写入部分获得了一些有价值的帮助。

我在这个临时文件中写了所有文件内容,我已经写了标题(其他文件的元数据)。我完成了这部分。

现在,在目标设备上,我想阅读这些元数据信息,并希望创建与我在主机平台上读取的文件相同的文件。

那么为什么我要在read_header函数中做什么?

可能我必须按照这个步骤

1) I have to create one file named as like `file[i].file_name`
2) I have to move at the position of file from where file contents is started 
3) Than I have to read one by one byte from this file up to `file[i].file_size` and write one by one byte to new created file which name is `file[i].file_name`.
4) For Second file what i have to do?

我被困在这里我必须使这个代码通用(动态),所以最多得到file_count的数量,它使我们被读取的文件。

我是正确的上述步骤和我必须在代码中为此更改?

输出:

File path : package_DIRA//a.txt
File path : package_DIRA//c.txt
File path : package_DIRA//b.txt

Write : File Count 3

Write : File Name size 6
Write : File Names a.txt
Write : File Size 9

Write : File Name size 6
Write : File Names c.txt
Write : File Size 5

Write : File Name size 6
Write : File Names b.txt
Write : File Size 10

File Name path : package_DIRA//a.txt
Number of Bytes Write in new file is 9
File Name path : package_DIRA//c.txt
Number of Bytes Write in new file is 5
File Name path : package_DIRA//b.txt
Number of Bytes Write in new file is 10

Success

Read : File Name Size 6
Read : File Names a.txt
Read : File Size 9
Read : File Name Size 6
Read : File Names c.txt
Read : File Size 5
Read : File Name Size 6
Read : File Names b.txt
Read : File Size 10

我的最终目标就像在read_header函数中我希望在hello目录中创建与从package_DIRA目录中读取的文件相同的文件。 我有file_sizefile_name个文件,但我必须从temporary file读取这些文件内容。

任何人都可以帮我解决这个问题。

感谢。

   #include <dirent.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rijndael.h"
#include "crc16.h"
#include "compression.h"

enum {
    MAX_FILES = 50
};

struct files {
    char *file_name;
    int file_size;
};

typedef struct file_header {
    int file_count;
    struct files file[MAX_FILES];
} metadata;

static void err_exit(const char *format, ...);
static metadata *create_header(const char *directory);
static void release_header(metadata *header);
static void write_header(FILE *fp, const metadata *header);
static metadata *read_header(FILE *fp);
void files_copy(const char *path, const char *newfilename);
void file_copy(const char *path, char *filename, const char *newfilename);

int main(int argc, char **argv) {
    if (argc != 3)
        err_exit("Usage: %s file directory\n", argv[0]);

    const char *name = argv[1];
    const char *path = argv[2];
    FILE *fp = fopen(name, "wb");

    if (fp == 0)
        err_exit("Failed to open file %s for writing (%d: %s)\n", name, errno,
                strerror(errno));

    metadata *header = create_header(path);
    write_header(fp, header);
    fclose(fp); // Ignore error on close
    release_header(header);

    //copy file contents
    files_copy(path, name);

    // Header reading

    if ((fp = fopen(name, "rb")) == 0) {
        printf("\nError\n");
        err_exit("Failed to open file %s for reading (%d: %s)\n",
                name, errno, strerror(errno));
    } else {
        printf("\nSuccess\n");
        metadata *read_info = read_header(fp);
        release_header(read_info);

        fclose(fp);
    }

    // Ignore error on close

    return 0;
}

void files_copy(const char *path, const char *newfilename) {

    DIR * dirp;
    struct dirent * entry;
    dirp = opendir(path);
    while ((entry = readdir(dirp)) != NULL) {

        if (entry->d_type == DT_REG) { /* If the entry is a regular file */

            file_copy(path, entry->d_name, newfilename);
        }
    }
    closedir(dirp);
    printf("\n");
}

void file_copy(const char *path, char *filename, const char *newfilename) {
    char file_path[2048];
    long file_size;
    int count = 0;
    strcpy(file_path, path);
    strcat(file_path, "/");
    strcat(file_path, filename);
    printf("\nFile Name path : %s", file_path);
    FILE *file = fopen(file_path, "rb");
    /* fopen returns 0, the NULL pointer, on failure */
    if (file == 0) {
        printf("\nCould not open file\n");
    } else {
        int readChar;
        FILE *newfile = fopen(newfilename, "ab");
        if (newfile == NULL) {
            printf("\nNew file open Failed\n");
        } else {
            while ((readChar = fgetc(file)) != EOF) {
                count++;
                fputc(readChar, newfile);
            }
            fclose(newfile);
            printf("\nNumber of Bytes Write in new file is %d", count);
        }
        fclose(file);
    }
}

static metadata *create_header(const char *path) {
    int file_count = 0;
    DIR * dirp = opendir(path);
    struct dirent * entry;
    if (dirp == 0) {
        err_exit("Failed to open directory %s (%d: %s)\n", path, errno,
                strerror(errno));
    }
    metadata *header = (metadata *) malloc(sizeof(metadata));
    if (header == 0) {
        err_exit("Failed to malloc space for header (%d: %s)\n", errno,
                strerror(errno));
    }
    header->file_count = 0;
    while ((entry = readdir(dirp)) != NULL && file_count < MAX_FILES) {
        // d_type is not portable - POSIX says you can only rely on d_name and d_ino
        if (entry->d_type == DT_REG) { /* If the entry is a regular file */
            // Avoid off-by-one under-allocation by using strdup()
            header->file[file_count].file_name = strdup(entry->d_name);
            if (header->file[file_count].file_name == 0)
                err_exit("Failed to strdup() file %s (%d: %s)\n",
                        entry->d_name, errno, strerror(errno));

            header->file[file_count].file_size = file_size(entry->d_name, path);
            file_count++;
        }
    }
    header->file_count = file_count;
    closedir(dirp);
    //printf("File Count : %d\n", file_count);
    return header;
}

static void write_header(FILE *fp, const metadata *header) {
    if (fwrite(&header->file_count, sizeof(header->file_count), 1, fp) != 1) {
        err_exit("Write error on file count (%d: %s)\n", errno, strerror(errno));
    }
    printf("\nWrite : File Count %d", header->file_count);
    const struct files *files = header->file;
    int i;
    for (i = 0; i < header->file_count; i++) {
        unsigned short name_len = strlen(files[i].file_name) + 1;
        if (fwrite(&name_len, sizeof(name_len), 1, fp) != 1) {
            err_exit("Write error on file name length (%d: %s)\n", errno,
                    strerror(errno));
        }
        printf("\n\nWrite : File Name size %d", name_len);
        if (fwrite(files[i].file_name, name_len, 1, fp) != 1) {
            err_exit("Write error on file name (%d: %s)\n", errno, strerror(
                    errno));
        }
        printf("\nWrite : File Names %s", files[i].file_name);
        if (fwrite(&files[i].file_size, sizeof(files[i].file_size), 1, fp) != 1) {
            err_exit("Write error on file size (%d: %s)\n", errno, strerror(
                    errno));
        }
        printf("\nWrite : File Size %d", files[i].file_size);
    }
    printf("\n");
}

static metadata *read_header(FILE *fp) {

    metadata *header = malloc(sizeof(*header));

    if (header == 0) {

        printf("Failed to malloc space for header \n");
        //err_exit("Failed to malloc space for header (%d:%s)\n", errno,
        //  strerror(errno));
    }
    if (fread(&header->file_count, sizeof(header->file_count), 1, fp) != 1)
        err_exit("Read error on file count (%d: %s)\n", errno, strerror(errno));
    struct files *files = header->file;
    int i;
    for (i = 0; i < header->file_count; i++) {

        system("mkdir hello");
        system("chmod 700 hello");
        unsigned short name_len;
        if (fread(&name_len, sizeof(name_len), 1, fp) != 1) {
            err_exit("Read error on file name length (%d: %s)\n", errno,
                    strerror(errno));
        }
        printf("\nRead : File Name Size %d", name_len);
        files[i].file_name = malloc(name_len);
        if (files[i].file_name == 0) {
            err_exit("Failed to malloc space for file name (%d:%s)\n", errno,
                    strerror(errno));
        }

        if (fread(files[i].file_name, name_len, 1, fp) != 1) {
            err_exit("Read error on file name (%d: %s)\n", errno, strerror(
                    errno));
        }
        printf("\nRead : File Names %s", files[i].file_name);
        if (fread(&files[i].file_size, sizeof(files[i].file_size), 1, fp) != 1) {
            err_exit("Read error on file size (%d: %s)\n", errno, strerror(
                    errno));
        }
        printf("\nRead : File Size %d", files[i].file_size);

    }
    return (header);
}

static void release_header(metadata *header) {
    int i;
    for (i = 0; i < header->file_count; i++) {
        /* Zap file name, and pointer to file name */
        memset(header->file[i].file_name, 0xDD, strlen(
                header->file[i].file_name) + 1);
        free(header->file[i].file_name);
        memset(&header->file[i].file_name, 0xEE,
                sizeof(header->file[i].file_name));
    }
    free(header);
}

static void err_exit(const char *format, ...) {
    va_list args;
    va_start(args, format);
    vfprintf(stderr, format, args);
    va_end(args);
    exit(EXIT_FAILURE);
}

int file_size(char *filename, char *path) {
    char file_path[1024];
    int file_size;
    strcpy(file_path, path);
    strcat(file_path, "/");
    strcat(file_path, filename);
    printf("File path : %s\n", file_path);
    FILE *file = fopen(file_path, "rb");
    if (file != NULL) {
        fseek(file, 0, SEEK_END);
        file_size = ftell(file);
        return file_size;
        fclose(file);
    }
}

0 个答案:

没有答案
相关问题