持久化

写一个文件容易,读一个文件难。健壮的程序应该能正确读取文件,还能处理坏文件。
数据描述是Lua的主要应用之一,从Lua发明以来,我们花了很多心血使他能够更快的编译和运行大的chunks。也即是说lua文件即可存储数据。

  1. --使用lua文件作为数据数据,并进行管理的例子。
  2. -------------- 数据文件data.lua
  3. Entry{
  4. author = "Donald E. Knuth",
  5. title = "Literate Programming",
  6. publisher = "CSLI",
  7. year = 1992
  8. }
  9. Entry{
  10. author = "Jon Bentley",
  11. title = "More Programming Pearls",
  12. publisher = "Addison-Wesley",
  13. year = 1990
  14. }
  15. -------------- 数据文件data.lua
  16. local authors = {} -- a set to collect authors
  17. function Entry (b) -- Entry即可作为统计工具,记录数据。
  18. if b.author then
  19. authors[b.author] = true
  20. end
  21. end

序列化

将数据转成字符流或字节流。

不带循环嵌套的表

  1. function serialize (o)
  2. if type(o) == "number" then
  3. io.write(o)
  4. elseif type(o) == "string" then
  5. io.write(string.format("%q", o))
  6. elseif type(o) == "table" then
  7. -- 如果是以下这种循环或者嵌套的表,就会死循环。
  8. -- a = {x=1, y=2; {3,4,5}}
  9. -- a[2] = a -- cycle
  10. -- a.z = a[1]
  11. a = {}
  12. io.write("{\n")
  13. for k,v in pairs(o) do
  14. io.write(" [")
  15. serialize(k)
  16. io.write("] = ")
  17. serialize(v)
  18. io.write(",\n")
  19. end
  20. io.write("}\n")
  21. else
  22. error("cannot serialize a " .. type(o))
  23. end
  24. end
  25. local t = {
  26. a=12,
  27. b='Lua',
  28. key='another "one"'
  29. }
  30. serialize(t)
  31. {
  32. ["a"] = 12,
  33. ["b"] = "Lua",
  34. ["key"] = "another \"one\"",
  35. }

带循环嵌套的表

  1. function basicSerialize (o) --一般序列化:numberstring
  2. if type(o) == "number" then
  3. return tostring(o)
  4. else -- assume it is a string
  5. return string.format("%q", o)
  6. end
  7. end
  8. -- name key
  9. -- value value值,可能是自循环table
  10. -- saved save表,保存已经序列化过的table,反之自循环table导致的死循环。
  11. 键值对:value(table) - name
  12. function save(name, value, saved)
  13. saved = saved or {}
  14. io.write(name, " = ")
  15. if type(value) == "number" or type(value) == "string" then
  16. io.write(basicSerialize(value), "\n")
  17. elseif type(value) == "table" then
  18. if saved[value] then
  19. io.write(saved[value], "\n")
  20. else
  21. saved[value] = name -- save name for next time
  22. io.write("{}\n") -- create a new table
  23. for k,v in pairs(value) do -- save its fields
  24. local fieldname = string.format("%s[%s]", name,
  25. basicSerialize(k))
  26. save(fieldname, v, saved)
  27. end
  28. end
  29. else
  30. error("cannot save a " .. type(value))
  31. end
  32. end
  33. ----------------------------------------
  34. a = {x=1, y=2; {3,4,5}}
  35. a[2] = a
  36. a.z = a[1]
  37. save('a', a) --序列化自循环表
  38. a = {}
  39. a[1] = {}
  40. a[1][1] = 3
  41. a[1][2] = 4
  42. a[1][3] = 5
  43. a[2] = a
  44. a["y"] = 2
  45. a["x"] = 1
  46. a["z"] = a[1]
  47. ----------------------------------
  48. a = {{"one", "two"}, 3}
  49. b = {k = a[1]}
  50. save('a', a) -- 不同save
  51. save('b', b) -- 不同save
  52. a = {}
  53. a[1] = {}
  54. a[1][1] = "one"
  55. a[1][2] = "two"
  56. a[2] = 3
  57. b = {}
  58. b["k"] = {}
  59. b["k"][1] = "one"
  60. b["k"][2] = "two"
  61. --------------------------------
  62. a = {{"one", "two"}, 3}
  63. b = {k = a[1]}
  64. local t = {}
  65. save('a', a, t) --共同save
  66. save('b', b, t) --共同save
  67. a = {}
  68. a[1] = {}
  69. a[1][1] = "one"
  70. a[1][2] = "two"
  71. a[2] = 3
  72. b = {}
  73. b["k"] = a[1]