问题:如何创建浏览器中的文件展示页面?
再论前端页面
交互页面分析
静态部分
- 表格,页面结构
动态部分
- 文件浏览路径 (Path)
- 文件列表(Table)
"<!DOCTYPE html>"
"<html>"
" <head>"
" <meta charset=\"utf-8\">"
" <title>D.T.Software</title>"
" <head>"
" <body>"
" <h1>DT4SW Http File Server</h1>"
" <hr/>"
" <h3>Path: %s</h3>"
" %s"
" <body>"
"<html>"
文件列表分析
静态
- 表格标题行
- 表格列表结构
动态部分
- 表格行数据
"<table border=\"1\" width=\"100%\">";
" <tr>"
" <th>File Name</th><th>File Type</th><th>File Size</th><th>Modify Time</th>"
" </tr>"
" <td><a href=\"%s\">%s</a></td><td>%s</td><td>%s</td><td>%s</td>"
" </tr>"
"</table>"
文件列表接口函数及数据结构
Table *CreateTable();
Table *InsertRow(Table *table, RowInfo *info);
char *ToTableString(Table *table);
void FreeTable(Table *table);
typedef void Table;
typedef struct {
char link[2048];
char name[255];
char type[32];
char size[32];
char time[32];
}RowInfo;
解决方案
CreateTable()
- 从堆空间创建表格标题行,并作为初始表格数据返回
InsertRow(table, info)
- 将 info 中的字符串进行表格行格式化,并添加到 table 末尾
ToTableString(table)
- 将 table 表格数据格式化为 HTML 字符串,并返回
表格动态创建关键代码
if (table && info) {
char *t = table;
int len = strlen(t);
char *buf = malloc(strlen(ROW_FORMAT) + sizeof(*info));
if (buf) {
sprintf(buf, ROW_FORMAT, info->link, info->name, info->type, info->size, info->time);
ret = realloc(t, len + strlen(buf) + 1);
ret = ret ? (strcpy(ret + len, buf), ret) : t;
} else {
ret = t;
}
free(buf);
}
页面动态创建代码
char *ToPageString(const char *path, char *ts)
{
char *ret = NULL;
if (path && ts && (ret = malloc(strlen(PAGE_FORMAT) + strlen(path) + strlen(ts) + 1))) {
sprintf(ret, PAGE_FORMAT, path, ts);
}
return ret;
}
编程实验:动态创建交互页面
main.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <time.h>
#include <fcntl.h>
#include <string.h>
#include "tcp_server.h"
#include "tcp_client.h"
#include "utility.h"
#include "page.h"
int main(int argc, char *argv[])
{
Table *t = CreateTable();
RowInfo ri = {"aa", "bbb", "cccc", "ddddd", "eeeeee"};
RowInfo rj = {"11", "222", "3333", "44444", "555555"};
t = InsertRow(t, &ri);
t = InsertRow(t, &rj);
char *ts = ToTableString(t);
char *page = ToPageString("test/path/folder", ts);
printf("%s\n", page);
free(page);
free(ts);
FreeTable(t);
return 0;
}
page.h
#ifndef PAGE_H
#define PAGE_H
typedef void Table;
typedef struct
{
char link[2048];
char name[255];
char type[32];
char size[32];
char time[32];
} RowInfo;
char* ToPageString(const char* path, const char* ts);
Table* CreateTable();
Table* InsertRow(Table* table, RowInfo* info);
char* ToTableString(Table* table);
void FreeTable(Table* table);
#endif // PAGE_H
page.c
#include "page.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
static const char* PAGE_FORMAT = "<!DOCTYPE html>"
"<html>"
" <head>"
" <meta charset=\"utf-8\">"
" <title>D.T.Software</title>"
" </head>"
" <body>"
" <h1>DT4SW Http File Server</h1>"
" <hr/>"
" <h3>Path: %s</h3>"
" %s"
" </body>"
"</html>";
static const char* TABLE_BEGIN = "<table border=\"1\" width=\"100%\">";
static const char* TABLE_TITLE = " <tr>"
" <th>File Name</th><th>File Type</th><th>File Size</th><th>Modify Time</th>"
" </tr>";
static const char* ROW_FORMAT = "<tr>"
" <td><a href=\"%s\">%s</a></td><td>%s</td><td>%s</td><td>%s</td>"
"</tr>";
static const char* TABLE_END = " </tr>"
"</table>";
char *ToPageString(const char *path, const char *ts)
{
char *ret = NULL;
if (path && ts && (ret = malloc(strlen(PAGE_FORMAT) + strlen(path) + strlen(ts) + 1))) {
sprintf(ret, PAGE_FORMAT, path, ts);
}
return ret;
}
Table *CreateTable()
{
const int TITLE_LEN = strlen(TABLE_TITLE);
char *ret = malloc(TITLE_LEN + 1);
if (ret) {
strcpy(ret, TABLE_TITLE);
}
return ret;
}
char *ToTableString(Table *table)
{
const int BEGIN_LEN = strlen(TABLE_BEGIN);
const int END_LEN = strlen(TABLE_END);
char *ret = NULL;
if (table && (ret = malloc(strlen(table) + BEGIN_LEN + END_LEN + 1))) {
strcpy(ret, TABLE_BEGIN);
strcpy(ret + BEGIN_LEN, table);
strcpy(ret + BEGIN_LEN + strlen(table), TABLE_END);
}
return ret;
}
Table *InsertRow(Table *table, RowInfo *info)
{
char *ret = NULL;
if (table && info) {
char *t = table;
int len = strlen(t);
char *buf = malloc(strlen(ROW_FORMAT) + sizeof(*info));
if (buf) {
sprintf(buf, ROW_FORMAT, info->link, info->name, info->type, info->size, info->time);
ret = realloc(t, len + strlen(buf) + 1);
ret = ret ? (strcpy(ret + len, buf), ret) : t;
} else {
ret = t;
}
free(buf);
}
return ret;
}
void FreeTable(Table *table)
{
free(table);
}
输出
<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>D.T.Software</title> </head> <body> <h1>DT4SW Http File Server</h1> <hr/> <h3>Path: test/path/folder</h3> <table border="1" width="100%"> <tr> <th>File Name</th><th>File Type</th><th>File Size</th><th>Modify Time</th> </tr><tr> <td><a href="aa">bbb</a></td><td>cccc</td><td>ddddd</td><td>eeeeee</td></tr><tr> <td><a href="11">222</a></td><td>3333</td><td>44444</td><td>555555</td></tr> </tr></table> </body></html>
思考
浏览器于文件服务器如何交互?
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。