Я хочу скопировать эту структуру в фиксированный блок памяти и записать в файл в двоичном режиме и прочитать эти данные из файла в фиксированный блок памяти. А затем скопировать эти данные с помощью memcpy в структуру.
Вам действительно не нужно создавать промежуточный буфер. Просто прочтите / напишите прямо в структуру. Вы делаете это, выполняя два чтения или записи для каждой операции «сохранения / восстановления». Иногда это называют «сериализацией».
Это проще и быстрее и не требует memcpy
.
Вот ваш код, отредактированный для этого:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
enum {
NODECOUNT = 20,
DATACOUNT = 128,
};
struct free_bitmap {
int *node_bitmap;
int *data_bitmap;
};
void
bitmap_alloc(struct free_bitmap *f)
{
f->node_bitmap = malloc(sizeof(int) * NODECOUNT);
f->data_bitmap = malloc(sizeof(int) * DATACOUNT);
}
void
bitmap_free(struct free_bitmap *f)
{
free(f->node_bitmap);
free(f->data_bitmap);
}
void
bitmap_write(int fd,struct free_bitmap *f)
{
write(fd,f->node_bitmap,sizeof(int) * NODECOUNT);
write(fd,f->data_bitmap,sizeof(int) * DATACOUNT);
}
void
bitmap_read(int fd,struct free_bitmap *f)
{
read(fd,f->node_bitmap,sizeof(int) * NODECOUNT);
read(fd,f->data_bitmap,sizeof(int) * DATACOUNT);
}
int
main()
{
struct free_bitmap f1;
struct free_bitmap f2;
bitmap_alloc(&f1);
int i;
for (i = 0; i < NODECOUNT; ++i)
f1.node_bitmap[i] = i;
int fd = open("test", O_RDWR | O_CREAT, 0600);
bitmap_write(fd,&f1);
printf("a");
lseek(fd, 0, SEEK_SET);
bitmap_alloc(&f2);
bitmap_read(fd,&f2);
for (i = 0; i < NODECOUNT; ++i)
printf("%d ", f1.node_bitmap[i]);
printf("\n");
bitmap_free(&f1);
bitmap_free(&f2);
return 0;
}
ОБНОВЛЕНИЕ:
То есть я хочу использовать этот файл как файловую систему. Например, напишите эту структуру в первый блок, а другую структуру во второй блок и размер блока 2 КБ. Поэтому я использую память кучи, чтобы исправить длину данных. Размер файла фиксированный и 1 МБ, например
Хорошо, вот версия, которая записывает несколько блоков и сравнивает результаты. Он выравнивает каждый по размеру блока 2 КБ, используя общий размер 1 МБ:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
enum {
NODECOUNT = 20,
DATACOUNT = 128,
BLOCKSIZE = 2 * 1024,
FILESIZE = 1024 * 1024,
NMAP = 5,
};
struct free_bitmap {
int *node_bitmap;
int *data_bitmap;
};
void
bitmap_alloc(struct free_bitmap *f)
{
f->node_bitmap = malloc(sizeof(int) * NODECOUNT);
f->data_bitmap = malloc(sizeof(int) * DATACOUNT);
}
void
bitmap_free(struct free_bitmap *f)
{
free(f->node_bitmap);
free(f->data_bitmap);
}
void
bitmap_write(int fd,struct free_bitmap *f)
{
ssize_t tot = 0;
tot += write(fd,f->node_bitmap,sizeof(int) * NODECOUNT);
tot += write(fd,f->data_bitmap,sizeof(int) * DATACOUNT);
tot = BLOCKSIZE - tot;
if (tot > 0)
lseek(fd,tot,SEEK_CUR);
}
void
bitmap_read(int fd,struct free_bitmap *f)
{
ssize_t tot = 0;
tot += read(fd,f->node_bitmap,sizeof(int) * NODECOUNT);
tot += read(fd,f->data_bitmap,sizeof(int) * DATACOUNT);
tot = BLOCKSIZE - tot;
if (tot > 0)
lseek(fd,tot,SEEK_CUR);
}
int
mapcmp(int mapidx,const char *tag,const int *lhs,const int *rhs,int count)
{
int i;
int bad = 0;
for (i = 0; i < count; ++i) {
if (lhs[i] != rhs[i]) {
printf("mapcmp: MISMATCH mapidx=%d tag=%s i=%d lhs=%d rhs=%d\n",
mapidx,tag,i,lhs,rhs);
bad = 1;
}
}
return bad;
}
int
main(void)
{
struct free_bitmap wlist[NMAP];
struct free_bitmap *wcur;
struct free_bitmap rlist[NMAP];
struct free_bitmap *rcur;
int off;
int i;
int mapidx;
int code;
int fd = open("test", O_RDWR | O_CREAT, 0600);
ftruncate(fd,FILESIZE);
// create blocks with unique test data
off = 0;
for (wcur = &wlist[0]; wcur < &wlist[NMAP]; ++wcur, off += 23) {
bitmap_alloc(wcur);
for (i = 0; i < NODECOUNT; ++i)
wcur->node_bitmap[i] = i + off;
for (i = 0; i < DATACOUNT; ++i)
wcur->data_bitmap[i] = i + off + 17;
bitmap_write(fd,wcur);
}
lseek(fd, 0, SEEK_SET);
for (rcur = &rlist[0]; rcur < &rlist[NMAP]; ++rcur) {
bitmap_alloc(rcur);
bitmap_read(fd,rcur);
}
code = 0;
// compare all data in all blocks
for (mapidx = 0; mapidx < NMAP; ++mapidx) {
wcur = &wlist[mapidx];
rcur = &rlist[mapidx];
if (mapcmp(mapidx,"NODE",rcur->node_bitmap,wcur->node_bitmap,NODECOUNT))
code = 1;
if (mapcmp(mapidx,"DATA",rcur->data_bitmap,wcur->data_bitmap,DATACOUNT))
code = 1;
}
// release all blocks
for (mapidx = 0; mapidx < NMAP; ++mapidx) {
bitmap_free(&wlist[mapidx]);
bitmap_free(&rlist[mapidx]);
}
printf("%s\n",code ? "FAIL" : "PASS");
return code;
}