便便代码人生

关注技术, 偶尔动动手

[原] 一种将数据表DataTable转为JSON格式的新方法

Posted by bianbian on 2010-09-23 03:17


本文Tags: , ,

最近实现一种将数据表转为JSON表示的新方法。
这种方法表示的JSON数据更省空间(尤其是网络传输,能省很多数据量),使用起来也很方便。
假设有这样一张数据表:

ID Name Location
1 周杰伦 香港
2 侯佩岑 台湾
3 张靓颖 大陆

一般的JSON表示方法为:

  1. [
  2. {"ID":1, "Name": "周杰伦", "Location": "香港"},
  3. {"ID":2, "Name": "侯佩岑", "Location": "台湾"},
  4. {"ID":3, "Name": "张靓颖", "Location": "大陆"}
  5. ]

可以看到,数据表的字段信息(column)在每条记录里都写了一遍,比较浪费空间。如果字段很多很长,甚至会比有效内容更多。随着记录数增加,浪费的数据量是很可观的。尤其像以前小百合BBS自己付流量费的时候,流量啊流量。。。。。。

我实现的表示方法产生的JSON格式是这样的:

  1. {
  2. "C":{"ID":0, "Name":1, "Location":2},
  3. "D":[
  4. [1, "周杰伦", "香港"],
  5. [2, "侯佩岑", "台湾"],
  6. [3, "张靓颖", "大陆"]
  7. ]}

这种方法将字段信息单独提取到C属性里,而D属性是纯粹的记录数据。
其实D属性本身已经完全能表示记录内容,C属性只是为了使用时方便。
在这短短几个字段及几条数据的极端情况下,已经省下几十字节。

下面对比使用方法,我承认这种方法稍微比通用的方法复杂一点,但是带来的节省,个人认为还是值得的:

  1. 通用方法取周杰伦:[0].Name
  2. 我的方法取周杰伦:D[0][C.Name]

下面是上述DataTable转JSON的C#代码

  1. using System;
  2. using System.Text;
  3. using System.Web.Script.Serialization;
  4. /// <summary>
  5. /// 一种JSON表示DataTable的新方法
  6. /// <see href="http://bianbian.org/technology/javascript/361.html" />
  7. /// </summary>
  8. public static class JsonUtil
  9. {
  10.     static JavaScriptSerializer _jss = new JavaScriptSerializer();
  11.  
  12.     /// <summary>
  13.     /// DataTable 转换成 JSON string。
  14.     /// </summary>
  15.     /// <param name="dt">需要转换的DataTable</param>
  16.     /// <returns>JSON结构字符串</returns>
  17.     public static string FromDataTable(System.Data.DataTable dt)
  18.     {
  19.         StringBuilder sb = new StringBuilder(256);
  20.         FormDataTable(dt, sb);
  21.         return sb.ToString();
  22.     }
  23.  
  24.     /// <summary>
  25.     /// DataTable 转换成 JSON string。
  26.     /// </summary>
  27.     /// <param name="dt">需要转换的DataTable</param>
  28.     /// <param name="sb">StringBuilder</param>
  29.     public static void FormDataTable(System.Data.DataTable dt, StringBuilder sb)
  30.     {
  31.         sb.Append("{C:{");
  32.         // -> {"ID":0, "Name":1}
  33.         for (int j = 0; j < dt.Columns.Count; j++)
  34.         {
  35.             if (j > 0)
  36.                 sb.Append(',');
  37.             sb.Append('"').Append(dt.Columns[j].ColumnName).Append('"')
  38.                 .Append(':').Append(j);
  39.         }
  40.         sb.Append("},D:[");
  41.  
  42.         for (int i = 0; i < dt.Rows.Count; i++)
  43.         {
  44.             if (i > 0)
  45.                 sb.Append(',');
  46.             sb.Append('[');
  47.             for (int j = 0; j < dt.Columns.Count; j++)
  48.             {
  49.                 if (j > 0)
  50.                     sb.Append(',');
  51.                 _jss.Serialize(dt.Rows[i][j], sb);
  52.             }
  53.             sb.Append(']');
  54.         }
  55.         sb.Append("]}");
  56.     }
  57. }
标签: , ,

遵守创作共用协议,转载请链接形式注明来自http://bianbian.org 做人要厚道

相关日志

Posted in C#, JavaScript, Technology | 11 Comments »

[原] 根据struct生成基于JSON-C的json_object代码(auto generate function of C struct to JSON)

Posted by bianbian on 2008-04-09 11:13


本文Tags: ,

上次讨论了C的struct结构体与JSON交互,并提出了能否自动把struct转为JSON的问题。
今天我总算解决了这个问题,虽然中间也想过传参数给一个函数集中处理,不过都是比较麻烦。我写了一个脚本,自动生成把struct的成员插入json_object的函数,底下页面有演示:auto generate function of C struct to JSON

标签: ,

遵守创作共用协议,转载请链接形式注明来自http://bianbian.org 做人要厚道

相关日志

Posted in C/C++, Technology | 6 Comments »

[原]一种blog日历的JSON压缩输出算法

Posted by bianbian on 2007-10-17 11:56


本文Tags: , , ,

一般高效的blog日历会将所有发表日期单独存储到js中,由客户端脚本负责输出日历链接。
以前都是按yyyymmdd输出blog日历的,如果发文多的话会特别长(特别是几年下来)。
最近用JSON输出blog日历的时候,发现一种更简单、更高效、更省数据量的方法:

{
"年份":["一月天", "二月天", ...., "五月天", .... , "十二月天"]
}

即年份作为JSON属性,值是十二个月天数构成的数组(五月天纯粹是增加关键字 – -)。
一个月最多有31天,如果用数字表示得用62个长度的字符。我决定用单个可打印字符的ASCII码代替。
在ASCII表里找了一段:从61-91(”=>?@ABCDEF……UVWXYZ[")满足要求(刚好是天数+60)
于是,原来比如2006每个月各发表1篇blog的数据从:

"20060111,20060212,20060313,20060414,20060515,20060616,20060717,20060818,20060919,20061020,20061121,20061222"

就可以压缩到(106是linux下struct tm的year,是1900+的,106+1900=2006):

{"106":["G","H","I","J","K","L","M","N","O","P","Q","R"]}

当然这只是一个特殊例子,实际上用户写blog都有一段时间的连续性。用这种办法输出的日历数据在
数据量大的情况下会更加省空间。(显然原来的方法重复了很多年份、月份数据)。
下面是一个勤劳用户从04到07年的blog日历(几乎天天有文章更新):
总数据量1K不到,如果用yyyymmdd的方法估计要是这个的5-6倍

b_date={"104":["=@DEGJO[","?CGHLP","BDEHIPTUY[","?ELNOPQRSUVZ","?ABGIKLMOPSTZ[",">CHIJLMNOPSUX",">AFGNT[",">GNOPQV","DUWZ","BDGHKNOQR","=?CDFLNOSTUVXYZ","=>?@BCDEFIJOPQSTWXYZ["],
"105":["?@BCEFGHIJMNOPQSTUV[","=>?@ABCGIJKLMNOPQRSTUVWX","=>?@ABCDEFGHIJKLMNOP","VWXYZ","=>ABCDEFGHIJLMN","BCDEFIJKLMOPQRSUWXYZ","=?@BCDEFGHIJNOPQRUVWY","=>BNRSUVWZ",">ABCDFGHIJKMOQTVWYZ","DEFGHIJLNOPQRUVW[","=>?@BCDEFGHIJKLQSTWXZ","=>@AHIJKNOPQRSVYZ"],
"106":["@ABFILMOPSTU",">DEFGIJKMNPQ",">BCDEFGHIJKOPQSTWXYZ","=?@ABEFGHIJLMNOPQRSTUVWX","DFLNORY[",">ABEFGHIJLOPQSUVWZ","=>ABCEFIJMNQUVW[","=>CEIJORSTUXYZ[","=>ACEGHKOPQRTUVWX","?@BDEFGHIJLNOPQSTUVWX","=>?AFHIJOPQSTWXYZ","=ABCGJNORUV["],
"107":[">@JKLNOPQRSTUVWXY[","=>?BDFGIKLSTUVWX",">@ABCEGHIKOPQRUVWXY[","=ABEFGHIKLMOPQSUVWXZ","?CDFHIJKLMNOQRSTUVWYZ","=?@ABCDEFGHIKLMNOPQRUWY","=?ADFGHIKMNOPSUWZ[","=>?@ABCDFGHIKLMNOPRSVWXY",">?@ABCDEFGIJKMNPQRTVXY",">ACDEGHJKL","",""]
}

用客户端Javascript解析的时候也比原来方便直接。原来需要split然后循环判断(如果排序了可以用二分法)。而JSON不需要这种解析,直接可以拿来用:使用String.fromCharCode(60+天)获得某天的字符,然后在当月中查找一下:

  1. //b_date={}
  2. function HasPost(Y, M, D)
  3. {
  4.     if (!b_date)
  5.         return false;
  6.     if (!b_date[Y])
  7.         return false;
  8.     var ds = b_date[Y][M];
  9.     return (ds.indexOf(String.fromCharCode(60+D)) > -1);
  10. }

(当然,如果要更省空间,甚至可以把各月的数据用一个字符串表示、用逗号隔开;不过这样就得在客户端split然后再解析了。我认为这是不必要的:每年只省下22个字节而已)

标签: , , ,

遵守创作共用协议,转载请链接形式注明来自http://bianbian.org 做人要厚道

相关日志

Posted in JavaScript, Technology | 3 Comments »

[原] C的struct和JSON交互

Posted by bianbian on 2007-07-15 04:55


本文Tags: ,

经过一天努力,现在百合涂鸦板用了JSON传递数据:http://bbs.nju.edu.cn/pntdoc?board=beginner
虽然把数据和页面分开了,不过觉得过程还是比较麻烦:
1)新建JSON对象,C读取struct,把值插入
2)输出to_JSON_String
3)Javascript解析JSON,通过JST模板生成页面

实在是比较麻烦,有没有可能把一个struct直接转成JSON对象?
或者直接丢struct的字节码(加上描述信息)过去让Javascript负责解析成JSON对象?

struct就是一段长度固定的二进制码,如果想个办法能和JSON对象之间转换,应该能大大解放C作FastCGI的生产力。我的意思是这样:
C:
struct obj {
char name[3];
int age;
};

JSON:
obj {
name: “12″,
age: int
}

让我想想。

标签: ,

遵守创作共用协议,转载请链接形式注明来自http://bianbian.org 做人要厚道

相关日志

Posted in C/C++, JavaScript, Technology | 1 Comment »

[译]JSON的C语言实现: JSON-C – A JSON implementation in C

Posted by bianbian on 2006-12-17 03:44


本文Tags:

[翻译] JSON-C能让你在C语言里轻松创建JSON对象,输出JSON字符串,解析JSON字符串成JSON对象。
test1.c的部分实例代码:

  1. struct json_object *my_array;
  2.   my_array = json_object_new_array();
  3.   json_object_array_add(my_array, json_object_new_int(1));
  4.   json_object_array_add(my_array, json_object_new_int(2));
  5.   json_object_array_add(my_array, json_object_new_int(3));
  6.   json_object_array_put_idx(my_array, 4, json_object_new_int(5));
  7.   printf("my_array=\n");
  8.   for(i=0; i < json_object_array_length(my_array); i++) {
  9.     struct json_object *obj = json_object_array_get_idx(my_array, i);
  10.     printf("\t[%d]=%s\n", i, json_object_to_json_string(obj));
  11.   }
  12.   printf("my_array.to_string()=%s\n", json_object_to_json_string(my_array));

地址: http://oss.metaparadigm.com/json-c/

[Original] JSON-C implements a reference counting object model that allows you to easily construct JSON objects in C, output them as JSON formatted strings and parse JSON formatted strings back into the C representation of JSON objects.

Copyright Metaparadigm Pte. Ltd. 2004, 2005. Michael Clark

如果不清楚JSON,请参考:http://www.json.org

标签:

遵守创作共用协议,转载请链接形式注明来自http://bianbian.org 做人要厚道

相关日志

Posted in C/C++, Technology | 5 Comments »