有这样一种需求,在做web 配网时需要把网页图片等文件转换成数组文件,并且根据路径等信息生成查找这些数组的文件,下面c语言是我写的一个例子。
//filename :make_web_file.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "dirent.h"
#define MAX_PATH_LENGTH 512
#define MAX_FILE_EXTENSION 9
#define FilePath "./web_pages"
unsigned long visit_dirs = 0;
unsigned long visit_files = 0;
//处理2部分
//1.web_pages/下html
//2.image/下图片
int listdir(char *path,FILE *fp_file_info,FILE *fp_dir_info)
{
int ret = 0;
DIR *ptr_dir;
struct dirent *dir_entry;
int i = 0;
char *child_path;
char *file_path;
child_path = (char*)malloc(sizeof(char)*MAX_PATH_LENGTH);
if(child_path == NULL)
{
printf("allocate memory for path failed.\n");
ret = -1;
goto listdir_exit;
}
memset(child_path, 0, sizeof(char)*MAX_PATH_LENGTH);
file_path = (char*)malloc(sizeof(char)*MAX_PATH_LENGTH);
if(file_path == NULL)
{
printf("allocate memory for file path failed.\n");
ret = -1;
goto listdir_exit;
}
memset(file_path, 0, sizeof(char)*MAX_PATH_LENGTH);
ptr_dir = opendir(path);
if(ptr_dir == NULL)
{
printf("Can`t open directory %s\n", path);
ret = -1;
goto listdir_exit;
}
while((dir_entry = readdir(ptr_dir)) != NULL)
{
if(dir_entry->d_type & DT_DIR)
{
if(strcmp(dir_entry->d_name,".") == 0 ||
strcmp(dir_entry->d_name,"..") == 0)
{
continue;
}
sprintf(child_path, "%s/%s", path, dir_entry->d_name);
printf("[DIR]%s\n", child_path);
fwrite(child_path,strlen(child_path),1,fp_dir_info);
fwrite("\r\n",strlen("\r\n"),1,fp_dir_info);
visit_dirs++;
listdir(child_path,fp_file_info,fp_dir_info);
}
if(dir_entry->d_type & DT_REG)
{
sprintf(file_path, "%s/%s", path, dir_entry->d_name);
printf("[FILE]%s\n", file_path);
fwrite(file_path,strlen(file_path),1,fp_file_info);
fwrite("\r\n",strlen("\r\n"),1,fp_file_info);
visit_files++;
}
}
listdir_exit:
if(child_path != NULL)
free(child_path);
child_path = NULL;
if(file_path != NULL)
free(file_path);
file_path = NULL;
return ret;
}
void is_capslk(char* arr_name,int arr_name_len,int is_capslk)
{//is_capslk 0原样输出 1转小写 2转大写
if(arr_name == NULL || arr_name_len == 0)
return;
int i;
if(is_capslk==1) //1转小写
{
for(i=0;i<arr_name_len;i++)
{
if(arr_name[i]>='A' && arr_name[i] <='Z')
arr_name[i]+=32;
}
}
else if(is_capslk==2) //1转大写
{
for(i=0;i<arr_name_len;i++)
{
if(arr_name[i]>='a' && arr_name[i] <='z')
arr_name[i]-=32;
}
}
return;
}
char * arr_name_get(char *file_path,char* arr_name,int arr_name_len)
{
if(file_path == NULL || arr_name == NULL)
return NULL;
char * PA = file_path;// + sizeof(FilePath);
int i;int i_bak=-1;
for(i=strlen(file_path)-1;i>=0;i--)
{
if(PA[i] == '/')
{
i_bak = i;
break;
}
}
if(i_bak==-1)
return NULL;
PA +=i_bak+1;
char * PB = strchr(PA,'.');
if(arr_name_len >= (PB-PA))
memcpy(arr_name,PA,PB-PA);
else
memcpy(arr_name,PA,arr_name_len);
return arr_name;
}
int file2arr_append(char *file_path,FILE *fp_out)
{
char buff[512];char arr_name[512];
FILE *pFile = fopen(file_path, "r");
if(pFile == NULL)
{
printf("path err :%s\n",file_path);
return -1;
}
if(fseek(pFile,0,SEEK_END) != 0)
{
printf("fseek file err\n");
fclose(pFile);
return -1;
}
unsigned int len = ftell(pFile); //获得待转换文件字节数
printf("%s size is %d\n",file_path,len);
memset(buff,0,sizeof(buff));
memset(arr_name,0,sizeof(arr_name));
arr_name_get(file_path,arr_name,sizeof(arr_name));
sprintf(buff,"\r\nstatic const unsigned char %sarr[%d]= { ",arr_name,len);
unsigned int head_len = strlen(buff);
fwrite(buff,head_len,1,fp_out);
fseek(pFile,0,SEEK_SET);
unsigned char dat;int ret=0;int i=0;
while( (ret = fread(&dat,1,1,pFile)) !=0)
{
if(ret == 1)
{
if(i%16 == 0)
{
fwrite("\r\n ",strlen("\r\n "),1,fp_out);
}
sprintf(buff,"0x%02X,",dat);
fwrite(buff,strlen(buff),1,fp_out);
i++;
}
else
{
printf("fread err\n");fclose(pFile);
return -1;
}
}
fwrite("\r\n};\r\n",strlen("\r\n};\r\n"),1,fp_out);
fclose(pFile);
return 0;
}
int find_char_num(char *fileName,char chr)
{
char* tmp=NULL;int chr_index = 0;
char* fileName_tmp = fileName;
do
{
tmp = NULL;
tmp=strchr(fileName_tmp,chr);
if(tmp != NULL)
{
chr_index++;
fileName_tmp = tmp+1;
}
}while(tmp !=NULL);
return chr_index;
}
int main(int argc, char* argv[])
{
// 1 web_file.c web_file.h
// 2 web_data.h
int i=0,j=0;
FILE *fp_file_info = fopen("file_info.txt","w+"); //用于记录FilePath下的文件信息
FILE *fp_dir_info = fopen("dir_info.txt","w+"); //用于记录FilePath下的目录信息
FILE *fp_web_file_c = fopen("web_file.c","w+"); //带生成的3个文件
FILE *fp_web_file_h = fopen("web_file.h","w+");
FILE *fp_web_data_h = fopen("web_data.h","w+");
if(fp_file_info == NULL || fp_dir_info == NULL ||\
fp_web_file_c == NULL || fp_web_file_h == NULL || fp_web_data_h == NULL)
{
printf("open file err\n");
goto exit0;
}
//把文件路径信息和目录路径记录在file_info.txt和dir_info.txt文件
listdir(FilePath,fp_file_info,fp_dir_info);
/***********************拿到文件路径信息***************************************/
fseek(fp_file_info,0,SEEK_SET);
unsigned char* *p_file_path = malloc(visit_files * sizeof(unsigned char*));
if(p_file_path == NULL)
goto exit0;
memset(p_file_path,0,visit_files*sizeof(unsigned char*));
for(i=0;i<visit_files;i++)
{
if(p_file_path[i] == NULL)
{
p_file_path[i] = malloc(MAX_PATH_LENGTH);
if(p_file_path[i] == NULL)
printf("malloc(MAX_PATH_LENGTH) fail!!!\n");
memset(p_file_path[i],0,MAX_PATH_LENGTH);
fscanf(fp_file_info,"%s",p_file_path[i]);
printf("%s\n",p_file_path[i]);
}
}
/***********************拿到目录路径信息***************************************/
fseek(fp_dir_info,0,SEEK_SET);
unsigned char* *p_dir_path = malloc(visit_dirs * sizeof(unsigned char*));
if(p_dir_path == NULL)
goto exit0;
memset(p_dir_path,0,visit_dirs*sizeof(unsigned char*));
for(i=0;i<visit_dirs;i++)
{
if(p_dir_path[i] == NULL)
{
p_dir_path[i] = malloc(MAX_PATH_LENGTH);
if(p_dir_path[i] == NULL)
printf("malloc(MAX_PATH_LENGTH) fail!!!\n");
memset(p_dir_path[i],0,MAX_PATH_LENGTH);
fscanf(fp_dir_info,"%s",p_dir_path[i]);
printf("%s\n",p_dir_path[i]);
}
}
//1. 生成web_data.h文件
fseek(fp_web_data_h,0,SEEK_SET);
fwrite("#ifndef __WEB_DATA_H__",strlen("#ifndef __WEB_DATA_H__"),1,fp_web_data_h);fwrite("\r\n",strlen("\r\n"),1,fp_web_data_h);
fwrite("#define __WEB_DATA_H__",strlen("#define __WEB_DATA_H__"),1,fp_web_data_h);fwrite("\r\n",strlen("\r\n"),1,fp_web_data_h);
fwrite("\r\n",strlen("\r\n"),1,fp_web_data_h);
for(i=0;i<visit_files;i++)
{
file2arr_append(p_file_path[i],fp_web_data_h);
}
fwrite("#endif",strlen("#endif"),1,fp_web_data_h);fwrite("\r\n",strlen("\r\n"),1,fp_web_data_h);
//2.生成web_file.c 根据 html action生成
char buff_tmp[1024];
fseek(fp_web_file_c,0,SEEK_SET);
fwrite("#include \"web_file.h\"",strlen("#include \"web_file.h\""),1,fp_web_file_c);fwrite("\r\n",strlen("\r\n"),1,fp_web_file_c);
fwrite("\r\n//子目录文件根据文件路径搜索文件数组",strlen("\r\n//子目录文件根据文件路径搜索文件数组"),1,fp_web_file_c);
for(i=0;i<visit_dirs;i++) //p_dir_path[i]
{
memset(buff_tmp,0,sizeof(buff_tmp));
sprintf(buff_tmp,"\r\nconst char *file_root_%s[] = {",p_dir_path[i]+strlen(FilePath)+1);
fwrite(buff_tmp,strlen(buff_tmp),1,fp_web_file_c);fwrite("\r\n ",strlen("\r\n "),1,fp_web_file_c);
for(j=0;j<visit_files;j++)
{
memset(buff_tmp,0,sizeof(buff_tmp));
memcpy(buff_tmp,p_dir_path[i],strlen(p_dir_path[i]));
buff_tmp[strlen(buff_tmp)] = '/'; //p_dir_path[i] 添加 /再比较
if(strstr(p_file_path[j],buff_tmp) != NULL)
{
memset(buff_tmp,0,sizeof(buff_tmp));
sprintf(buff_tmp,"\"%s%s\",",p_dir_path[i]+strlen(FilePath),p_file_path[j]+strlen(p_dir_path[i]));
fwrite(buff_tmp,strlen(buff_tmp),1,fp_web_file_c);fwrite("\r\n ",strlen("\r\n "),1,fp_web_file_c);
}
}
fseek(fp_web_file_c,-4,SEEK_CUR);
fwrite("\r\n };\r\n",strlen("\r\n };\r\n"),1,fp_web_file_c);
}
fwrite("\r\n//主目录文件根据action搜索文件数组",strlen("\r\n//主目录文件根据action搜索文件数组"),1,fp_web_file_c);
char *p_st = NULL;
char *p_ed = NULL;
char buff_tmp_bak[1024];
char buff_tmp_bak_bak[1024];
memset(buff_tmp,0,sizeof(buff_tmp));
sprintf(buff_tmp,"\r\nconst char *file_root[] = {");
fwrite(buff_tmp,strlen(buff_tmp),1,fp_web_file_c);fwrite("\r\n ",strlen("\r\n "),1,fp_web_file_c);
fwrite("\"/\",",strlen("\"/\","),1,fp_web_file_c);fwrite("\r\n ",strlen("\r\n "),1,fp_web_file_c);
fwrite("\"/index.html\",",strlen("\"/index.html\","),1,fp_web_file_c);fwrite("\r\n ",strlen("\r\n "),1,fp_web_file_c);
for(i=0;i<visit_files;i++) //p_dir_path[i]
{
if( find_char_num(p_file_path[i],'/') == 2) // ./web_pages/login.html 是根目录文件
{
FILE *pfiletmp = fopen(p_file_path[i], "r");
while (!feof(pfiletmp))
{
memset(buff_tmp_bak,0,sizeof(buff_tmp_bak));
fgets(buff_tmp_bak, sizeof(buff_tmp_bak), pfiletmp);
//printf("%s", buff_tmp_bak);
if((strstr(buff_tmp_bak,"method=\"get\"")!= NULL || strstr(buff_tmp_bak,"method=\"GET\"")!= NULL )&& strstr(buff_tmp_bak,"action=\"")!= NULL)
{
//memset(buff_tmp,0,sizeof(buff_tmp));
p_st = strstr(buff_tmp_bak,"action=\"");
p_st +=strlen("action=\"");
p_ed = strstr(p_st,"\"");
memset(buff_tmp_bak_bak,0,sizeof(buff_tmp_bak_bak));
memcpy(buff_tmp_bak_bak,p_st,p_ed-p_st);
memset(buff_tmp,0,sizeof(buff_tmp));
sprintf(buff_tmp,"\"%s?\",",buff_tmp_bak_bak);
fwrite(buff_tmp,strlen(buff_tmp),1,fp_web_file_c);fwrite("\r\n ",strlen("\r\n "),1,fp_web_file_c);
}
else if(strstr(buff_tmp_bak,"method=")!= NULL && strstr(buff_tmp_bak,"action=\"")!= NULL)
{
p_st = strstr(buff_tmp_bak,"action=\"");
p_st +=strlen("action=\"");
p_ed = strstr(p_st,"\"");
memset(buff_tmp_bak_bak,0,sizeof(buff_tmp_bak_bak));
memcpy(buff_tmp_bak_bak,p_st,p_ed-p_st);
memset(buff_tmp,0,sizeof(buff_tmp));
sprintf(buff_tmp,"\"%s\",",buff_tmp_bak_bak);
fwrite(buff_tmp,strlen(buff_tmp),1,fp_web_file_c);fwrite("\r\n ",strlen("\r\n "),1,fp_web_file_c);
}
}
fclose(pfiletmp);
}
}
fseek(fp_web_file_c,-4,SEEK_CUR);
fwrite("\r\n };\r\n",strlen("\r\n };\r\n"),1,fp_web_file_c);
//3.生成web_file.h 根据 web_file.c h和html <!--#-->生成
fseek(fp_web_file_h,0,SEEK_SET);
fwrite("#ifndef __WEB_FILE_H__",strlen("#ifndef __WEB_FILE_H__"),1,fp_web_file_h);fwrite("\r\n",strlen("\r\n"),1,fp_web_file_h);
fwrite("#define __WEB_FILE_H__",strlen("#define __WEB_FILE_H__"),1,fp_web_file_h);fwrite("\r\n",strlen("\r\n"),1,fp_web_file_h);
fwrite("\r\n",strlen("\r\n"),1,fp_web_file_h);
fwrite("#include \"web_data.h\"",strlen("#include \"web_data.h\""),1,fp_web_file_h);fwrite("\r\n",strlen("\r\n"),1,fp_web_file_h);
fwrite("\r\n",strlen("\r\n"),1,fp_web_file_h);
fseek(fp_web_file_c,0,SEEK_SET);
while (!feof(fp_web_file_c))
{
memset(buff_tmp_bak,0,sizeof(buff_tmp_bak));
fgets(buff_tmp_bak, sizeof(buff_tmp_bak), fp_web_file_c);
if(strstr(buff_tmp_bak,"const char *file_root")!= NULL)
{
p_st = strstr(buff_tmp_bak,"const char *file_root");
p_ed = strstr(buff_tmp_bak,"]");
p_ed +=strlen("]");
memset(buff_tmp_bak_bak,0,sizeof(buff_tmp_bak_bak));
memcpy(buff_tmp_bak_bak,p_st,p_ed-p_st);
memset(buff_tmp,0,sizeof(buff_tmp));
sprintf(buff_tmp,"extern %s;",buff_tmp_bak_bak);
fwrite(buff_tmp,strlen(buff_tmp),1,fp_web_file_h);fwrite("\r\n",strlen("\r\n"),1,fp_web_file_h);
}
}
int tag_num=1;
for(i=0;i<visit_files;i++) //p_dir_path[i]
{
tag_num=1;
if( find_char_num(p_file_path[i],'/') == 2) // ./web_pages/login.html 是根目录文件
{
FILE *pfiletmp = fopen(p_file_path[i], "r");
while (!feof(pfiletmp))
{
memset(buff_tmp_bak,0,sizeof(buff_tmp_bak));
fgets(buff_tmp_bak, sizeof(buff_tmp_bak), pfiletmp);
if(strstr(buff_tmp_bak,"<!--#")!= NULL && strstr(buff_tmp_bak,"-->")!= NULL)
{
//memset(buff_tmp,0,sizeof(buff_tmp));
p_st = strstr(buff_tmp_bak,"<!--#");
p_ed = strstr(p_st,"-->");
p_ed +=strlen("-->");
memset(buff_tmp_bak_bak,0,sizeof(buff_tmp_bak_bak));
memcpy(buff_tmp_bak_bak,p_st,p_ed-p_st); // <!--#aplist-->"
memset(buff_tmp_bak,0,sizeof(buff_tmp_bak));
arr_name_get(p_file_path[i],buff_tmp_bak,sizeof(buff_tmp_bak));
is_capslk(buff_tmp_bak,strlen(buff_tmp_bak),2);//WIRELESS_CONFIG
memset(buff_tmp,0,sizeof(buff_tmp));
sprintf(buff_tmp,"#define TAG_%s%d \"%s\"",buff_tmp_bak,tag_num,buff_tmp_bak_bak);
fwrite(buff_tmp,strlen(buff_tmp),1,fp_web_file_h);fwrite("\r\n",strlen("\r\n"),1,fp_web_file_h);
tag_num++;
}
}
fclose(pfiletmp);
}
}
fwrite("#endif",strlen("#endif"),1,fp_web_file_h);fwrite("\r\n",strlen("\r\n"),1,fp_web_file_h);
exit0:
if(p_file_path != NULL)
{
for(i=0;i<visit_files;i++)
{
if(p_file_path[i] != NULL)
{
free(p_file_path[i]);p_file_path[i] == NULL;
}
}
free(p_file_path);p_file_path = NULL;
}
fclose(fp_file_info);remove("file_info.txt");
fclose(fp_dir_info);remove("dir_info.txt");
fclose(fp_web_file_c);
fclose(fp_web_file_h);
fclose(fp_web_data_h);
printf("Total DIR: %ld, Total FILE: %ld\n", visit_dirs, visit_files);
return 0;
}
/*
https://blog.csdn.net/zhuyi2654715/article/details/7605051
struct dirent
{
long d_ino; /* inode number 索引节点号
off_t d_off; /* offset to this dirent 在目录文件中的偏移
unsigned short d_reclen; /* length of this d_name 文件名长
unsigned char d_type; /* the type of d_name 文件类型
char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符
}
*/
在linux下编译make_web_file.c并运行可以生成
web_data.h ---------->网页数组
web_file.c ----------->网页数组查找文件
wen_file.h
3个文件
web_pages 目录下存放html文件
路径如下
执行输出信息