我正在處理的平臺有非常嚴格的內存限制,我試圖找到一種解析大型JSON字符串的方法,而不需要最多加載超過幾百字節進入記憶。 JSON字符串存儲在一個更大的芯片(閃存)中的文件中。解析比內存大的JSON字符串
有兩件事情,我真的不能找到一個很好的解決方案爲:
- 訪問通過指定「路徑」像
foo["bar"][2]
一定的價值。 (如果該值是一個數組/對象,那麼我們只應該返回它是一個數組/對象的事實,也可能它是空的或不空的。) - 迭代在數組/對象內的任何對象/數組JSON。
所以基本上我需要的功能,調用它時,一步解析JSON一步,既節約,我們確實需要繼續解析部分。
對於界面我不認爲有可能有類似exampleJson["aa"].2.["gg]
,但我設法得到真正接近:exampleJson["aa"].2.["gg"]()
。這會導致函數被調用,然後可以輕鬆訪問{'aa',2,'gg'}並從文件中讀取/解析json。
這是到目前爲止我的代碼,但我真的不知道該怎麼繼續:
https://repl.it/HfwS/2
-- Looks complicated, but is pretty simple. Using meta tables we create a json interface that can almost be accessed as if it was a lua table.
-- E.g. example["aa"][2]["gg"]() ; the only difference is that we have to use parentheses at the end
-- The problematic part starts where it says `THIS IS WHERE THE JSON PARSING WOULD HAPPEN`
json = {}
setmetatable(json, {
__call = function(path)
local jsonFile = _file.open(filePath)
local fileLen = jsonFile:stat().size
local patternTable = {} -- Will store `{'aa',2,'gg'}` for `example.['aa'].[2]['gg']()`
local fakeJson = {}
setmetatable(fakeJson, {
__index = function (t, k)
patternTable[#patternTable+1] = k
return fakeJson
end;
__call = function()
-- THIS IS WHERE THE JSON PARSING WOULD HAPPEN --
-- The patternTable contains {'aa',2,'gg'} at this point
-- Loop through the json file char by char
local valueToReturn = ''
local filePos = 0
for i=1, fileLen do
jsonFile:seek("set", filePos)
local currentChar = jsonFile:read(1) -- read character at current position
filePos = filePos + 1
-- print(currentChar)
-- Now the question is, how do we parse the json?
print('Magic to parse the json')
-- valueToReturn = ?
end
patternTable = {} -- Reset the patternTable
return valueToReturn
end;
})
return fakeJson
end;
})
local fakeParsedJson = json('example.json')
local value = fakeParsedJson["aa"][2]["gg"]() -- Notice the `()` in the end
print(value)