RWInterface.h
/**********************************************************\
In this example, we keep a 2048 byte as file header.
the detail is as follows:
the first four byte indicate the number of total files been
saved. and a long type value is followed to indicate the end
of this file. then the left space is kept for the files to
be saved. in this 2048 header, each file to be saved have a
120 byte, which is begin with data begin offset and data end
offset, then a length of filename is followed, and the filename
is the last part. the real file data is stored int the space
start from 2048;
\**********************************************************/
#ifndef __YL__READER__WRITER__
#define __YL__READER__WRITER__
#include <cstdio>
#include <cstdlib>
#include <cstring>
/**********************************************************\
structure for data operation
must be initialized before calling the reader,
and allocate memory for this structure
\**********************************************************/
typedef struct FileContent
{
char OriginalFileName[64];
long DataSize;
char* Buf;
}FileContent;
/**********************************************************\
Read file
Input:
pf: pointer to the file from which we read data
index: as the writer accept data by file, this index indicate
the order we save files
fc: structure which we get the data
\**********************************************************/
void ReadFile(FILE* pf, int index, FileContent* fc);
/**********************************************************\
Write Files
input:
pf: Pointer to an opened file which we can save data to
filename: name of a file where we can get the data to save
\**********************************************************/
void WriteFile(FILE* pf, char* filename);
#endif
// reader.cpp
#include "RWInterface.h"
// index start from 0
void ReadFile(FILE* pf, int index, FileContent* fc)
{
fflush(pf);
int filenum;
fseek(pf, 0, SEEK_SET);
long cur = ftell(pf);
fread(&filenum, sizeof(filenum), 1, pf);
cur = ftell(pf);
if (filenum < index + 1)
{
printf("Error index\n");
return;
}
long filetailpos;
fread(&filetailpos, sizeof(filetailpos), 1, pf);
int headsize = sizeof(long) + sizeof(int);
fseek(pf, headsize + index * 120, SEEK_SET);
long startpos, endpos;
fread(&startpos, sizeof(startpos), 1, pf);
fread(&endpos, sizeof(endpos), 1, pf);
if (endpos > filetailpos)
{
printf("Broken File!\n");
return;
}
long sz = endpos - startpos;
int len;
fread(&len, sizeof(len), 1, pf);
char* filename = new char[len];
fread(filename, len, 1, pf);
fseek(pf, startpos, SEEK_SET);
fread(fc->Buf, sz, 1, pf);
fc->DataSize = sz;
strcpy(fc->OriginalFileName, filename);
fflush(pf);
}
// writer.cpp
#include "RWInterface.h"
void WriteFile(FILE* pf, char* filename)
{
fflush(pf);
FILE* tmppf;
tmppf = fopen(filename, "rb+");
int headerOffset = sizeof(long) + sizeof(int);
int filecnt = 0;
long Tailpos = 0;
fseek(pf, 0, SEEK_END);
long filelen = ftell(pf);
bool flag = false;
if ( filelen > 2048)
{
fseek(pf,0,SEEK_SET);
flag = true;
fread(&filecnt, sizeof(int), 1, pf);
if (2048 - 120 * (filecnt ) - headerOffset < 120)
{
return;
}
fread(&Tailpos, sizeof(long), 1, pf);
}else{
fflush(pf);
fwrite(&filecnt, sizeof(filecnt), 1, pf);
fwrite(&Tailpos, sizeof(Tailpos), 1, pf);
Tailpos = 2048;
}
fflush(pf);
fseek(pf, headerOffset + 120 * (filecnt), SEEK_SET);
fwrite(&Tailpos, sizeof(Tailpos), 1, pf); // 开始位置
long endpos = 0;
fwrite(&endpos, sizeof(endpos), 1, pf); // 结束位置
int len = strlen(filename) + 1;
fwrite(&len, sizeof(len), 1, pf);
fwrite(filename, len, 1, pf);
fwrite("\0", sizeof("\0"), 1, pf);
if (!flag)
{
fseek(pf, 2048, SEEK_SET);
}
else
{
fseek(pf, Tailpos, SEEK_SET);
}
char ch;
fflush(tmppf);
fseek(tmppf,0,SEEK_END);
long length = ftell(tmppf);
char *data = new char[length];
fseek(tmppf,0,SEEK_SET);
fread(data, length, 1, tmppf);
fwrite(data, length, 1, pf);
long npos = ftell(pf);
fseek(pf, headerOffset + 120 * (filecnt) + sizeof(long), SEEK_SET);
fwrite(&npos, sizeof(npos), 1, pf);
fseek(pf,0,SEEK_SET);
filecnt += 1;
fwrite(&filecnt, sizeof(filecnt), 1, pf); // 文件数
fwrite(&npos, sizeof(npos), 1, pf); // 文件尾巴位置
delete data;
fclose(tmppf);
fflush(pf);
}
// test.cpp
#include "RWInterface.h"
#include <iostream>
using namespace std;
int main()
{
FILE* pf;
pf = fopen("data.jsd", "wb+");
WriteFile(pf, "2.jpg");
WriteFile(pf, "3.jpg");
FileContent* pfc = new FileContent;
pfc->Buf = (char*) malloc(1024*1024);
ReadFile(pf, 1, pfc);
FILE* npf = fopen("2.COPY.jpg", "wb+");
fwrite(pfc->Buf, pfc->DataSize, 1, npf);
free(pfc->Buf);
delete pfc;
fclose(pf);
fclose(npf);
return 0;
}