基于C语言的内存文件实现
2017-03-14 18:24
471 查看
在有些应用场景中,设备并没有磁盘设备,因此不能像PC机上那样使用标准C库的文件操作APIs,但又希望能实现一些文件操作。或者有时候在网上下载的一些应用库,这些库里应用到了文件操作APIs,但是移植的目标机器上又不具有磁盘设备。
为了实现在内存中模拟出文件的操作函数,下面将贴出部分代码,可实现基本功能:
memfile.h 文件
memfile.c 文件
后续继续添加修改
写于:2017/03/14 下午18:20
分割线——————————————————————————————
优化读写后
memfile.h文件
memfile.c文件
更新于 2017/03/16
为了实现在内存中模拟出文件的操作函数,下面将贴出部分代码,可实现基本功能:
memfile.h 文件
/* * memfile.h * * Copyright (C) 2017-2027, Albert.song. * * This document provides a memory file interface, easy to store files in * memory rather than disk, some applications do not need to output data * to disk, so the available memory file instead. */ #ifndef _MEMFILE_H__ #define _MEMFILE_H__ #include "jmorecfg.h" #include <malloc.h> #include <string.h> #define MAX_FAILNAME 256 #define FILENODESIZE 4096 #define MSEEK_CUR 1 #define MSEEK_END 2 #define MSEEK_SET 0 struct MFileNode { char lpBuffer[FILENODESIZE]; struct MFileNode *next; }; typedef struct { char *filename; INT32 offset; INT32 data_length; struct MFileNode *header; } MEMFILE; #define M_Malloc(size_len) malloc((size_t)(size_len)) #define M_Free(ptr) free((void*)(ptr)) #define M_Memcpy(to,from,count) memcpy((void*)(to),(void*)(from),(size_t)(count)) MEMFILE *mopen(const char * filename, const char * mode); int mclose(MEMFILE *stream); int mflush(MEMFILE *stream); size_t mwrite(void* buf, size_t size, size_t count, MEMFILE *stream); size_t mread(void* buf, size_t size, size_t count, MEMFILE *stream); int mseek(MEMFILE *stream, long int offset, int origin); #endif
memfile.c 文件
/* * memfile.c * * Copyright (C) 2017-2027, Albert.song. * * This document provides a memory file interface, easy to store files in * memory rather than disk, some applications do not need to output data * to disk, so the available memory file instead. */ /* this is not a core library module, so it doesn't define JPEG_INTERNALS */ #include "memfile.h" #define NULL ((void*)0) static int _mstrlen(const char *str,int max) { int i = 0; for (i = 0; i < max; i++) { if (0 == str[i]){ break; } } return i; } static char *_mstrcpy(char *str1, const char *str2) { char * s1; s1 = str1; while (*str2 != '\0'){ *str1++ = *str2++; } *str1++ = *str2++; return s1; } static char *_mGetFileCurentPtr(size_t *remain, struct MFileNode **curnode, MEMFILE *stream) { struct MFileNode *node = NULL; struct MFileNode *next = NULL; UINT8 * ptr; size_t cnt = stream->offset / FILENODESIZE + 1; next = stream->header; while (cnt && NULL != next){ node = next; next = node->next; cnt--; } if (node == NULL) return NULL; cnt = stream->offset % FILENODESIZE; ptr = node->lpBuffer + cnt; *remain = FILENODESIZE - cnt; if (curnode) *curnode = node; return ptr; } static struct MFileNode* _mAddNode(MEMFILE *stream) { struct MFileNode *node = NULL; struct MFileNode *next = NULL; struct MFileNode *ptr = NULL; ptr = (struct MFileNode *)M_Malloc(sizeof(struct MFileNode)); if (NULL == ptr){ return NULL; } ptr->next = NULL; if (NULL == stream->header){ stream->header = ptr; } else{ next = stream->header; while (NULL != next){ node = next; next = node->next; } node->next = ptr; } return ptr; } MEMFILE *mopen(const char * filename, const char * mode) { MEMFILE *mFile; int len; mFile = M_Malloc(sizeof(MEMFILE)); if (NULL == mFile){ return mFile; } len = _mstrlen(filename, MAX_FAILNAME); mFile->filename = (UINT8 *)M_Malloc((len + 2)*sizeof(char)); if (NULL == mFile->filename){ M_Free(mFile); return NULL; } _mstrcpy(mFile->filename, filename); mFile->data_length = 0; mFile->offset = 0; mFile->header = NULL; return mFile; } int mflush(MEMFILE *stream) { return 0; } int mclose(MEMFILE *stream) { struct MFileNode *node; struct MFileNode *next; mflush(stream); next = stream->header; while (NULL != next){ node = next; next = node->next; M_Free(node); } M_Free(stream->filename); M_Free(stream); return 0; } size_t mwrite(void* buf, size_t size, size_t count, MEMFILE *stream) { size_t remain; struct MFileNode *node; char * CurPtr; size_t copy_len; size_t totall; totall = size * count; CurPtr = _mGetFileCurentPtr(&remain,NULL, stream); if (NULL == CurPtr){ node = _mAddNode(stream); if (NULL == node) return -1; CurPtr = node->lpBuffer; remain = FILENODESIZE; } while (totall){ copy_len = totall < remain ? totall : remain; M_Memcpy(CurPtr, buf, copy_len); totall -= copy_len; remain -= copy_len; CurPtr += copy_len; stream->offset += copy_len; stream->data_length += copy_len; buf = (void*)((char*)buf + copy_len); if (0 == remain){ node = _mAddNode(stream); if (NULL == node){ totall = size * count - totall; return totall/size; } CurPtr = node->lpBuffer; remain = FILENODESIZE; } } return count; } size_t mread(void* buf, size_t size, size_t count, MEMFILE *stream) { char * CurPtr; struct MFileNode *node; size_t remain; size_t dataless; size_t totall; size_t copy_len; totall = size * count; CurPtr = _mGetFileCurentPtr(&remain, &node, stream); while (totall){ dataless = stream->data_length - stream->offset; if (dataless < remain){ remain = dataless; } copy_len = totall < remain ? totall : remain; M_Memcpy(buf, CurPtr, copy_len); stream->offset += copy_len; totall -= copy_len; buf = (void*)((char*)buf + copy_len); CurPtr += copy_len; remain -= copy_len; dataless -= copy_len; if (0 == dataless){ totall = size * count - totall; return totall / size; } if (0 == remain){ node = node->next; if (NULL == node){ totall = size * count - totall; return totall / size; } CurPtr = node->lpBuffer; remain = FILENODESIZE; } } totall = size * count - totall; return totall / size; } int mseek(MEMFILE *stream, long int offset, int origin) { switch (origin){ case MSEEK_CUR:stream->offset += offset; break; case MSEEK_END:stream->offset = stream->data_length + offset; break; case MSEEK_SET:stream->offset = offset; break; default:return -1; } if (stream->offset > stream->data_length){ stream->offset = stream->data_length; } return 0; }
后续继续添加修改
写于:2017/03/14 下午18:20
分割线——————————————————————————————
优化读写后
memfile.h文件
/* * memfile.h * * Copyright (C) 2017-2027, Albert.song. * * This document provides a memory file interface, easy to store files in * memory rather than disk, some applications do not need to output data * to d0e6 disk, so the available memory file instead. */ #ifndef _MEMFILE_H__ #define _MEMFILE_H__ #include "jmorecfg.h" #include <malloc.h> #include <string.h> #define MAX_FAILNAME 256 #define FILENODESIZE 4096 #define MSEEK_CUR 1 #define MSEEK_END 2 #define MSEEK_SET 0 struct MFileNode { char lpBuffer[FILENODESIZE]; struct MFileNode *next; }; typedef struct { char *filename; INT32 offset; INT32 data_length; INT32 remain; char *curptr; struct MFileNode *header; struct MFileNode *curnode; struct MFileNode *endnode; } MEMFILE; #define M_Malloc(size_len) malloc((size_t)(size_len)) #define M_Free(ptr) free((void*)(ptr)) #define M_Memcpy(to,from,count) memcpy((void*)(to),(void*)(from),(size_t)(count)) MEMFILE *mopen(const char * filename, const char * mode); int mclose(MEMFILE *stream); int mflush(MEMFILE *stream); int merror(MEMFILE *stream); size_t mwrite(void* buf, size_t size, size_t count, MEMFILE *stream); size_t mread(void* buf, size_t size, size_t count, MEMFILE *stream); int mseek(MEMFILE *stream, long int offset, int origin); #endif
memfile.c文件
/* * memfile.c * * Copyright (C) 2017-2027, Albert.song. * * This document provides a memory file interface, easy to store files in * memory rather than disk, some applications do not need to output data * to disk, so the available memory file instead. */ /* this is not a core library module, so it doesn't define JPEG_INTERNALS */ #include "memfile.h" #define NULL ((void*)0) static int _mstrlen(const char *str,int max) { int i = 0; for (i = 0; i < max; i++) { if (0 == str[i]){ break; } } return i; } static char *_mstrcpy(char *str1,int sizeInByte, const char *str2) { char * s1; s1 = str1; while (*str2 != '\0' && sizeInByte){ *str1++ = *str2++; sizeInByte--; } *str1++ = *str2++; return s1; } static int _mMoveToCurentPtrByOffset(MEMFILE *stream) { struct MFileNode *node = NULL; struct MFileNode *next = NULL; size_t cnt = stream->offset / FILENODESIZE + 1; next = stream->header; while (cnt && NULL != next){ node = next; next = node->next; cnt--; } if (NULL == node){ stream->curnode = node; stream->curptr = NULL; stream->remain = 0; return 0; } cnt = stream->offset % FILENODESIZE; stream->remain = FILENODESIZE - cnt; stream->curnode = node; stream->curptr = node->lpBuffer + cnt; return 0; } MEMFILE *mopen(const char * filename, const char * mode) { MEMFILE *mFile; int len; mFile = M_Malloc(sizeof(MEMFILE)); if (NULL == mFile){ return mFile; } len = _mstrlen(filename, MAX_FAILNAME); mFile->filename = (char *)M_Malloc((len + 2)*sizeof(char)); if (NULL == mFile->filename){ M_Free(mFile); return NULL; } _mstrcpy(mFile->filename,256, filename); mFile->data_length = 0; mFile->offset = 0; /*offset from first element*/ mFile->remain = 0; /*current node remain empty space*/ mFile->curptr = NULL; mFile->header = NULL; mFile->curnode = NULL; mFile->endnode = NULL; return mFile; } int mflush(MEMFILE *stream) { return 0; } int merror(MEMFILE *stream) { return 0; } int mclose(MEMFILE *stream) { struct MFileNode *node; struct MFileNode *next; mflush(stream); next = stream->header; while (NULL != next){ node = next; next = node->next; M_Free(node); } M_Free(stream->filename); M_Free(stream); return 0; } size_t mwrite(void* buf, size_t size, size_t count, MEMFILE *stream) { size_t copy_len; size_t totall; totall = size * count; while (totall){ if (0 == stream->remain){ //if one block is full if (NULL == stream->header){ //first write struct MFileNode *allocNode; allocNode = (struct MFileNode *)M_Malloc(sizeof(struct MFileNode)); if (NULL == allocNode){ break; } allocNode->next = NULL; stream->header = allocNode; stream->endnode = allocNode; stream->curnode = allocNode; } else if (stream->curnode != stream->endnode){ //if There are blocks behind stream->curnode = stream->curnode->next; } else{ //we need to alloc more block struct MFileNode *allocNode; allocNode = (struct MFileNode *)M_Malloc(sizeof(struct MFileNode)); if (NULL == allocNode){ break; } stream->curnode->next = allocNode; allocNode->next = NULL; stream->endnode = allocNode; stream->curnode = allocNode; } stream->remain = FILENODESIZE; stream->curptr = stream->curnode->lpBuffer; } copy_len = totall < stream->remain ? totall : stream->remain; M_Memcpy(stream->curptr, buf, copy_len); totall -= copy_len; stream->remain -= copy_len; stream->curptr += copy_len; stream->offset += copy_len; stream->data_length += copy_len; buf = (void*)((char*)buf + copy_len); } // if (totall == size * count) // return -1; return (size * count - totall) / size; } size_t mread(void* buf, size_t size, size_t count, MEMFILE *stream) { size_t dataless; size_t totall; size_t copy_len; totall = size * count; while (totall){ dataless = stream->data_length - stream->offset; if (0 == dataless){ totall = size * count - totall; return totall / size; } if (0 == stream->remain){ if (NULL == stream->header){ totall = size * count - totall; return totall / size; } if (stream->curnode == stream->endnode){ totall = size * count - totall; return totall / size; } stream->curnode = stream->curnode->next; stream->remain = FILENODESIZE; stream->curptr = stream->curnode->lpBuffer; } copy_len = stream->remain; if (dataless < stream->remain){ copy_len = dataless; } copy_len = totall < copy_len ? totall : copy_len; M_Memcpy(buf, stream->curptr, copy_len); stream->offset += copy_len; totall -= copy_len; buf = (void*)((char*)buf + copy_len); stream->curptr += copy_len; stream->remain -= copy_len; } totall = size * count - totall; return totall / size; } int mseek(MEMFILE *stream, long int offset, int origin) { switch (origin){ case MSEEK_CUR:stream->offset += offset; break; case MSEEK_END:stream->offset = stream->data_length + offset; break; case MSEEK_SET:stream->offset = offset; break; default: return -1; } if (stream->offset > stream->data_length){ stream->offset = stream->data_length; } if (stream->offset < 0){ stream->offset = 0; } return _mMoveToCurentPtrByOffset(stream); }
更新于 2017/03/16
相关文章推荐
- 基于POSIX在Linux下C语言实现读取整个目录文件[Get a List of Files in a Directory with C]
- linux平台下基于C语言实现遍历文件目录
- 基于哈夫曼(haffuman)算法的文件压缩的实现(C语言
- 基于Huffman树的文件压缩原理及C语言实现(二)
- 基于哈夫曼(haffuman)算法的文件压缩的实现(C语言)(转)
- 基于Huffman树的文件压缩原理及C语言实现(一)
- Linux环境下C语言实现简单的基于文件的学生信息管理系统
- c语言 实现按行读取文件。把内容按照第三种内存模型打包数据传出,把行数通过函数参数传出
- 【c语言】通讯录的简单实现文件版本(动态开辟内存)
- 通讯录c语言实现(动态内存开辟&文件存储)
- c语言实现mmap内存映射读取文件和文件加密
- 基于RTOS的c语言实现http文件上传
- 【转】用C语言实现将一个文件读入内存中(分享转载)
- 自己实现的C语言string.h 头文件的字符串函数与几个内存操作函数
- 用C语言实现将一个文件读入内存中
- AJAX实现基于WEB的文件上传的进度控制
- AJAX实现基于WEB的文件上传的进度控制
- AJAX实现基于WEB的文件上传的进度控制
- AJAX实现基于WEB的文件上传的进度控制
- C语言实现用程序数据段空间模拟内存的动态分配