我要从目录创建一个带有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_size
和file_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);
}
}