2016-01-01 2 views
5

Я пытаюсь сериализовать и десериализовать объект, который содержит несколько буферов, однако десериализация результирующей строки из JSON.stringify() с JSON.parse() не позволяет правильно воссоздать Буферы.Как десериализовать вложенный буфер с помощью JSON.parse

var b64 = 'Jw8mm8h+agVwgI/yN1egchSax0WLWXSEVP0umVvv5zM='; 
var buf = new Buffer(b64, 'base64'); 

var source = { 
    a: { 
     buffer: buf 
    } 
}; 

var stringify = JSON.stringify(source); 
var parse = JSON.parse(stringify); 

console.log("source: "+source.a.buffer.constructor.name); 
console.log("parse: "+parse.a.buffer.constructor.name); 

Выдает поток вывода:

source: Buffer 
parse: Object 

Это имеет смысл, так как выход из Buffer.toJSON() создает простой объект, как так:

{ 
    type: "Buffer", 
    data: [...] 
} 

Я предполагаю, что я мог пересечь результирующий объект ищет суб объекты, которые имеют вышеуказанные свойства и преобразовывают их обратно в буфер, однако я считаю, что должно быть более элегантное решение с использованием JSON.parse(), которое мне не хватает.

+1

Нет, нет ничего более элегантного. Единственными структурированными типами данных, поддерживаемые JSON, являются объекты и массивы. 'JSON.parse' ничего не знает о' Buffer'. Метод Buffer.toJSON просто переводит буфер в нечто, что 'JSON.parse' может понять. – Barmar

+2

Вы можете передать функцию [«reviver»] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Using_the_reviver_parameter) на 'JSON.parse' в порядке чтобы избежать ручного обхода. Когда вы найдете свойство 'buffer', вы берете значение и вручную создаете и возвращаете свой' Buffer'. –

+0

@squint мы думали то же самое, извините, если я «украл» ваш ответ :-) – robertklep

ответ

11

Вы можете использовать reviver function, который проверяет, является ли объект выглядит как строковой Buffer и создать надлежащий экземпляр из него:

var parse = JSON.parse(stringify, (k, v) => { 
    if (
    v !== null   && 
    typeof v === 'object' && 
    'type' in v   && 
    v.type === 'Buffer' && 
    'data' in v   && 
    Array.isArray(v.data)) { 
    return new Buffer(v.data); 
    } 
    return v; 
}); 
+0

Просто любопытно, откуда взялись «тип» и «данные»? –

+0

@squint - это свойства объекта, к которому привязана «Буфер». – robertklep

+0

Я не получаю эти свойства, когда строю буфер. Ты уверен? –

2

С JSON сериализацию Buffer с до:

{ 
    type: "Buffer", 
    data: [...] 
} 

Вы можете просто проверить type и переинициализировать буфер:

if (source.buf.type === 'Buffer') { 
    source.buf = new Buffer(source.buf.data); 
} 
+0

Я уверен, что он знает, как создать буфер. Он спрашивает, как он автоматически разбирается с буфером. * «... Я мог бы пересечь результирующий объект, ищущий объекты, имеющие вышеуказанные свойства, и преобразовать их обратно в буфер, однако я считаю, что должно быть более элегантное решение ...» * –

+0

И он, вероятно, не имеют «источник». Я действительно сомневаюсь, что он фактически выполняет 'stringify', за которым следует' parse'. –

+0

@squint Упс, следовало бы читать более внимательно. Ответ Роберклапа делает то же самое. –

Смежные вопросы