基于C语言的内存文件实现
来源:互联网 发布:淘宝买家秀图片对比 编辑:程序博客网 时间:2024/05/21 09:52
在有些应用场景中,设备并没有磁盘设备,因此不能像PC机上那样使用标准C库的文件操作APIs,但又希望能实现一些文件操作。或者有时候在网上下载的一些应用库,这些库里应用到了文件操作APIs,但是移植的目标机器上又不具有磁盘设备。
为了实现在内存中模拟出文件的操作函数,下面将贴出部分代码,可实现基本功能:
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 0struct 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 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 0struct 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
0 0
- 基于C语言的内存文件实现
- 基于C语言的内存池的设计与实现
- 基于C语言的内存池的设计与实现
- 基于C语言的内存池的设计与实现
- 基于C语言的内存池的设计与实现
- 基于C语言的内存池的设计与实现
- 基于RTOS的c语言实现http文件上传
- 数据结构和算法C语言实现:链表的实现(基于动态内存分配)
- 【转】基于C语言的内存池的设计与实现
- 基于C语言的文件加密技术
- 基于数组的队列实现(C语言)
- 基于C语言:长跳转的实现
- 基于C语言实现的Ping程序
- 基于C语言实现的Ping程序
- 基于C语言的状态机实现技术
- 基于C语言的状态机实现技术
- 基数排序(基于C语言的实现)
- 基于C语言实现的扫雷游戏
- 【第二十二颗】容器---容器的定义
- View的工作流程
- VS2010、gSOAP创建WebService
- (原创)我对未来的人类的发展,以及AI技术发展的一些思考。
- matlab基本知识
- 基于C语言的内存文件实现
- 快速排序算法
- 【OpenCV学习笔记】九、实例应用(二)鼠标截图程序及滑动条视频播放程序
- 【总结型文章】用python爬虫抓站的一些技巧总结(代理、浏览器、登录、多线程等)
- 浏览器调用webservice方法
- 【第二十二课】容器---Collections类中的常用方法使用
- Hadoop实践(三)---Hadoop API 之 ToolRunner
- Vuejs学习系列(十七)--模板语法(三)
- CSDN Markdown简明教程