2012-06-30 8 views
7

Veo cómo puedo escribir objetos en los archivos como se describe aquí: How can I save objects to files in Node.js?, pero ¿hay alguna manera de tomar un objeto y escribirlo de forma que pueda volver a cargar el objeto en la memoria, incluidos sus métodos?escribiendo objetos js a los archivos (incluidos los métodos) en nodejs?

+2

Las funciones de escritura y lectura presentan un gran riesgo de inyección. Consideraría las implicaciones de seguridad de esta decisión. –

+0

Estoy de acuerdo con Anthony. Si realmente lo necesita, simplemente puede guardar el código JavaScript, luego cargarlo y llamar a 'eval' en él. – freakish

+0

Estoy de acuerdo con las preocupaciones de seguridad. Solo estoy jugando con una idea. ¡Gracias! – luisgo

Respuesta

6

Como dijo antes @AnthonySottile, esto puede ser extremadamente peligroso y no estoy seguro de que haya alguna vez un buen caso de uso para él, pero solo para patadas y risas necesitaría escribir su propio serializador recursivo. Algo como esto:

var toString = Object.prototype.toString; 

function dump_object(obj) { 
    var buff, prop; 
    buff = []; 
    for (prop in obj) { 
     buff.push(dump_to_string(prop) + ': ' + dump_to_string(obj[prop])) 
    } 
    return '{' + buff.join(', ') + '}'; 
} 

function dump_array(arr) { 
    var buff, i, len; 
    buff = []; 
    for (i=0, len=arr.length; i<len; i++) { 
     buff.push(dump_to_string(arr[i])); 
    } 
    return '[' + buff.join(', ') + ']'; 
} 

function dump_to_string(obj) { 
    if (toString.call(obj) == '[object Function]') { 
     return obj.toString(); 
    } else if (toString.call(obj) == '[object Array]') { 
     return dump_array(obj); 
    } else if (toString.call(obj) == '[object String]') { 
     return '"' + obj.replace('"', '\\"') + '"'; 
    } else if (obj === Object(obj)) { 
     return dump_object(obj); 
    } 
    return obj.toString(); 
} 

Esto manejar la mayoría de los tipos, pero siempre existe la posibilidad de que un bicho raro mezclarlo por lo yo no usaría esto en la producción. Después de revertir la seriación es tan fácil como:

eval('var test = ' + dump_to_string(obj)) 
+3

O_O ¿Por qué estás reinventando la rueda? Defina el método 'toJSON' para la serialización personalizada de un objeto, ej. ' .prototype.toJSON'. Para una mayor flexibilidad, defina un [replacer para 'JSON.stringify'] (https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/JSON/stringify#Syntax). –

+0

@RobW No sabía nada de eso. Muy útil, gracias! – Trevor

+0

Muy útil. ¡Gracias! – luisgo

0

Hace poco escribió shovejs: http://shovemedia.github.com/shovejs/ para manejar exactamente este tipo de cosas. YMMV: aún no lo he probado con Node.

Convierte una estructura de objeto tipado en JSON (que luego guardaría en el disco) y puede inflar esa estructura de nuevo en objetos tipeados incluyendo el objeto adecuado -> referencias de objeto etc. Para que quede claro, las definiciones de método/clase NO están serializados. El sistema simplemente espera que las clases registradas de Modelo/Fábrica disponibles durante la serialización también estén disponibles durante la deserialización.

Disculpas de antemano por no haber publicado algunos ejemplos sencillos.

edición: la técnica es un trucado asumir lo que Rob W menciona en su comentario a continuación

1

La pregunta es bastante antiguo, pero no pude encontrar en cualquier lugar alguna solución sencilla a la pregunta de serialización eficaz en JavaScript.
Se podría usar BSON (representación de objetos internos MongoDB) que utiliza un formato binario para representar objetos en la memoria.

no pude encontrar algún vínculo con la documentación, pero el code is well documented y se me ocurrió algo similar:

fs = require 'fs' 
bson = require('bson').BSONPure.BSON 

obj = { 
    string: "test", 
    func: (s) -> 
    console.log s 
} 

fs.writeFile 'test.txt', bson.serialize(obj, false, false, true), (err) -> 
    return console.log("Err : #{err}") if err 
    fs.readFile 'test.txt', (err, file) -> 
    return console.log("Err : #{err}") if err 
    deserialized = bson.deserialize file, evalFunctions: true 
    deserialized.func deserialized.string // Outputs 'text', as expected 

Es coffee-script pero el código es bastante simple de entender para todos.

+0

Cuidado con la opción 'evalFunctions: true' ya que permitirá la ejecución de javascript (ver https://gist.github.com/DinisCruz/245716893d783ea740ea) –

Cuestiones relacionadas