返回> 网站首页 

[原创]Property list文件格式 - Safari浏览器Bookmarks.plist文件解析

yoours2011-10-23 21:48:23 阅读 1568

简介一边听听音乐,一边写写文章。

一、Property list文件格式介绍
http://en.wikipedia.org/wiki/Property_list

二、plist文件格式解析开源代码
C#代码 https://github.com/animetrics/PlistCS
safari浏览器各个plist文件解析代码 http://jafat.sourceforge.net/

三、商业的plist解析软件
http://www.icopybot.com/plist-editor.htm

四、基于C#的PlistCS解析
PlistCS解析safari浏览器的plist文件不支持中文的问题解决:

       1. 开源代码中的函数修改,见红色部分。
        private static object parseBinary(int objRef)
        {
            byte header = objectTable[offsetTable[objRef]];
            switch (header & 0xF0)
            {
                case 0:
                    {
                        //If the byte is
                        //0 return null
                        //9 return true
                        //8 return false
                        return (objectTable[offsetTable[objRef]] == 0) ? (object)null : ((objectTable[offsetTable[objRef]] == 9) ? true : false);
                    }
                case 0x10:
                    {
                        return parseBinaryInt(offsetTable[objRef]);
                    }
                case 0x20:
                    {
                        return parseBinaryReal(offsetTable[objRef]);
                    }
                case 0x30:
                    {
                        return parseBinaryDate(offsetTable[objRef]);
                    }
                case 0x40:
                    {
                        return parseBinaryByteArray(offsetTable[objRef]);
                    }
                case 0x50:
                    {
                        return parseBinaryString(offsetTable[objRef]);
                    }
                case 0xD0:
                    {
                        return parseBinaryDictionary(objRef);
                    }
                case 0xA0:
                    {
                        return parseBinaryArray(objRef);
                    }
                case 0x60://该类型为中文字符串
                    {
                        // 中文utf8
                        return parseBinaryUnicodeString(offsetTable[objRef]);
                    }
            }
            throw new Exception("This type is not supported");
        }

        2. 扩展的解析中文的函数
        private static object parseBinaryUnicodeString(int headerPosition)
        {
            byte header = objectTable[headerPosition];
            int byteCount = 2 * (header & 0xf);
            int byteStartPosition;
            if (byteCount < 30)
            {
                byteStartPosition = headerPosition + 1;
            }
            else
            {
                byteCount = objectTable[headerPosition + 2] * 2;
                byteStartPosition = headerPosition + 2 + 1;
            }

            byte[] Unicodebytes = objectTable.GetRange(byteStartPosition, byteCount).ToArray();
            byte bybyte;
            for (int i = 0; i < byteCount; i+=2)
            {
                bybyte = Unicodebytes[i];
                Unicodebytes[i] = Unicodebytes[i + 1];
                Unicodebytes[i + 1] = bybyte;
            }

            return Encoding.GetEncoding("UNICODE").GetString(Unicodebytes);
        }


修改源代码中函数,并添加中文扩展函数。
这样就完成了中文解析的支持。

五、显示解析的内容
  Dictionary<string, object> dict = (Dictionary<string, object>)Plist.readPlist(Application.StartupPath + @".\Bookmarks.plist");
  MyType(dict);

        void MyDictionary(object obj)
        {
            Dictionary<string, object> objDictionary = (Dictionary<string, object>)(obj);
            foreach (string key in objDictionary.Keys)
            {
                MyType(key);
                MyType(objDictionary[key]);
            }
        }

        void MyList(object obj)
        {
            List<object> objList = (List<object>)(obj);
            for (int i = 0; i < objList.Count; i++)
            {
                MyType(objList[i]);
            }
        }

        String MyString(object obj)
        {
            System.Diagnostics.Debug.WriteLine(obj.ToString());
            return obj.ToString();
        }

        void MyInt32(object obj)
        {
            System.Diagnostics.Debug.WriteLine((Int32)obj);
        }

        void MyType(object obj)
        {
            if (obj.GetType().Name == "Dictionary`2")
            {
                MyDictionary(obj);
            }
            else if (obj.GetType().Name == "List`1")
            {
                MyList(obj);
            }
            else if (obj.GetType().Name == "String")
            {
                MyString(obj);
            }
            else if (obj.GetType().Name == "Int32")
            {
                MyInt32(obj);
            }
            else
            {
                MyString(obj.GetType().Name);
            }
        }
微信小程序扫码登陆

文章评论

1568人参与,0条评论