elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Introducción a Git (Primera Parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  Como guardar un índice de ficheros
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Como guardar un índice de ficheros  (Leído 2,873 veces)
Bob_Ale

Desconectado Desconectado

Mensajes: 29


Ver Perfil
Como guardar un índice de ficheros
« en: 9 Octubre 2015, 20:21 pm »

Hola!

Estoy haciendo un programa en C# para crear un índice de ficheros para despues usar este índice en otras aplicaciones.

La verdad es que creo que ya lo tengo terminado pero tengo una duda.
¿Como o en que formato o estructura guardar el índice?

Por ahora busco todos los directorios que quiero indexar y los guardo en una estructura.
Después estoy salvando dicha estructura en un fichero XML. Que en C# guardar una estructura en un XML es super sencillo y rápido.

¿Pero es la mejor manera,  guardar un índice en un XML?

Enviado desde mi GT-I9300 mediante Tapatalk


En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.878



Ver Perfil
Re: Como guardar un índice de ficheros
« Respuesta #1 en: 9 Octubre 2015, 23:15 pm »

Estoy haciendo un programa en C# para crear un índice de ficheros para despues usar este índice en otras aplicaciones.

¿Pero es la mejor manera,  guardar un índice en un XML?

Suponiendo que hablemos de una base de datos de uso local (cuyo contenido llámese índice de archivos), entonces un archivo Xml es una manera ideal si lo que quieres es generar un archivo de texto plano que sea accesible/legible por el humano y sencillamente parseable por la máquina (vease también una estructura CSV, aunque a mi siempre me ha parecido algo muy, muy feo), de lo contrario, y si realmente nos debemos obsesionar por el rendimiento, entonces podrías serializar los datos en un archivo binario, a falta de mencionar un método más óptimo que tal vez puedo desconocer.

También habría que tener en cuenta la forma en que contruyas el Xml y también como lo cargas, me refiero a la lógica que emplees (por ejemplo instanciar un XmlWriter para escribir en el archivo poco a poco, o usar directamente el XmlSerializer) y los tiempos de respuesta de estas lógicas de tu algoritmo, pero si hablamos de una simple serialización de datos en Xml o Binario, entonces la velocidad de carga/lectura varia apenas unos milisegundos con cantidades de datos normales (1-100 mb).

Dicen que el serializador protobuf da mejores resultados que utilizando los serializadores de la librería de clases de .Net Framework, pero nunca lo he probado ya que no manejo una cantidad de datos que podamos denominar "Big Data" y por ende no me interesa romperme el cerebro para optimizar hasta tal punto ...y creo que tu tampoco necesitarás llegar hasta ese extremo, de todas formas por si te interesa lo puedes descargar aquí:
https://github.com/google/protobuf

En fin, por un lado tenemos la serialización XML y por otro la binaria, ¿para que más opciones?.

¿Cual es "la mejor manera" entre estas dos?, pues depende de las necesidades de cada uno, pero en lo que respecta a rendimiento para salir de dudas he realizado un pequeño test, donde he obtenido todas las rutas absolutas de mi sistema de archivos, y estos han sido los resultados:

Cita de: Resultado de ejecución
Total file amount......: 165,465 files.
FileSystem.Xml filesize: 18.88 MB.
FileSystem.Dat filesize: 16.51 MB.

Method Name: SerializeXml
Elapsed Time: 00:00:00:254 ms

Method Name: SerializeBin
Elapsed Time: 00:00:00:161 ms

Method Name: DeserializeXml
Elapsed Time: 00:00:00:327 ms

Method Name: DeserializeBin
Elapsed Time: 00:00:00:281 ms

Como se puede comprobar, el archivo resultante Xml ocupa unos MB más que el binario, y también tarda más en cargar. Los nombres de los métodos tienen nombres self-explanatory, creo que no es necesario explicar su funcionalidad.

El código fuente parcial, en VB.Net:

( Para resumir lo que ocurre, simplemente obtengo la ruta absoluta de todos los archivos del disco duro "C:\", y seguidamente uso la class BinaryFormatter y XmlSerializer para serializar los datos, mientras que con un StopWatch mido el tiempo de ejecución de ambos tipos de serialización y deserialización. )
Código
  1. Imports System.IO
  2.  
  3. Public NotInheritable Class Form1 : Inherits Form
  4.  
  5.    Dim fileSystemPaths As String()
  6.    Const xmlFilePath As String = ".\FileSystem.xml"
  7.    Const binFilePath As String = ".\FileSystem.dat"
  8.  
  9.    Private Sub Form1_Shown() Handles MyBase.Shown
  10.  
  11.        Me.fileSystemPaths = Utils.FileDirSearcher.GetFilePaths("C:\", SearchOption.AllDirectories).ToArray
  12.  
  13.        Utils.Misc.MeasureAction(AddressOf SerializeXml, writeResultInConsole:=True)
  14.        Utils.Misc.MeasureAction(AddressOf SerializeBin, writeResultInConsole:=True)
  15.  
  16.        Utils.Misc.MeasureAction(AddressOf DeserializeXml, writeResultInConsole:=True)
  17.        Utils.Misc.MeasureAction(AddressOf DeserializeBin, writeResultInConsole:=True)
  18.  
  19.        Dim sb As New StringBuilder
  20.        With sb
  21.            .AppendLine(String.Format("Total file amount......: {0} files.", Me.fileSystemPaths.Count.ToString("n0")))
  22.            .AppendLine(String.Format("FileSystem.Xml filesize: {0} MB.", (New FileInfo(xmlFilePath).Length / (1024 * 1024)).ToString("n2")))
  23.            .AppendLine(String.Format("FileSystem.Dat filesize: {0} MB.", (New FileInfo(binFilePath).Length / (1024 * 1024)).ToString("n2")))
  24.        End With
  25.  
  26.        Console.WriteLine(sb.ToString)
  27.  
  28.    End Sub
  29.  
  30.    Private Sub SerializeXml()
  31.        Utils.SerializationUtil.Serialize(Me.fileSystemPaths, xmlFilePath, SerializationFormat.Xml)
  32.    End Sub
  33.  
  34.    Private Sub SerializeBin()
  35.        Utils.SerializationUtil.Serialize(Me.fileSystemPaths, binFilePath, SerializationFormat.Binary)
  36.    End Sub
  37.  
  38.    Private Sub DeserializeXml()
  39.        Dim fileSystemFromXml As String() = Utils.SerializationUtil.Deserialize(Of String())(xmlFilePath, SerializationFormat.Xml)
  40.    End Sub
  41.  
  42.    Private Sub DeserializeBin()
  43.        Dim fileSystemFromBin As String() = Utils.SerializationUtil.Deserialize(Of String())(binFilePath, SerializationFormat.Binary)
  44.    End Sub
  45.  
  46. End Class

El código fuente de la solución completa:
http://www.mediafire.com/download/u167fme23z6p5ju/WindowsApplication1.rar

PD: C# y VB.Net son dos lenguajes (casi)idénticos internamente hablando, ya que ambos forman parte de la plataforma .Net, compilan mediante el CIL de Microsoft y se administra u optimiza mediante el JIT/NGen, así que podemos asumir que el test es igual de válido para dicho lenguaje, por si alguien tenía dudas.

Saludos.


« Última modificación: 9 Octubre 2015, 23:24 pm por Eleкtro » En línea



Bob_Ale

Desconectado Desconectado

Mensajes: 29


Ver Perfil
Re:
« Respuesta #2 en: 10 Octubre 2015, 07:56 am »

Muchas gracias Elektro!
Una respuesta muy completa. La estudiare con mucha atención.

Me preocupa (obsesiona) el rendimiento.
Esta índice se construirá en local, pero el acceso al índice será por red y desde distintos equipos.
No me preocupa si es legible o no.

Enviado desde mi GT-I9300 mediante Tapatalk
En línea

Bob_Ale

Desconectado Desconectado

Mensajes: 29


Ver Perfil
Re: Re: Como guardar un índice de ficheros
« Respuesta #3 en: 14 Octubre 2015, 08:31 am »

Suponiendo que hablemos de una base de datos de uso local (cuyo contenido llámese índice de archivos), entonces un archivo Xml es una manera ideal si lo que quieres es generar un archivo de texto plano que sea accesible/legible por el humano y sencillamente parseable por la máquina (vease también una estructura CSV, aunque a mi siempre me ha parecido algo muy, muy feo), de lo contrario, y si realmente nos debemos obsesionar por el rendimiento, entonces podrías serializar los datos en un archivo binario, a falta de mencionar un método más óptimo que tal vez puedo desconocer.

También habría que tener en cuenta la forma en que contruyas el Xml y también como lo cargas, me refiero a la lógica que emplees (por ejemplo instanciar un XmlWriter para escribir en el archivo poco a poco, o usar directamente el XmlSerializer) y los tiempos de respuesta de estas lógicas de tu algoritmo, pero si hablamos de una simple serialización de datos en Xml o Binario, entonces la velocidad de carga/lectura varia apenas unos milisegundos con cantidades de datos normales (1-100 mb).

Dicen que el serializador protobuf da mejores resultados que utilizando los serializadores de la librería de clases de .Net Framework, pero nunca lo he probado ya que no manejo una cantidad de datos que podamos denominar "Big Data" y por ende no me interesa romperme el cerebro para optimizar hasta tal punto ...y creo que tu tampoco necesitarás llegar hasta ese extremo, de todas formas por si te interesa lo puedes descargar aquí:
https://github.com/google/protobuf

En fin, por un lado tenemos la serialización XML y por otro la binaria, ¿para que más opciones?.

¿Cual es "la mejor manera" entre estas dos?, pues depende de las necesidades de cada uno, pero en lo que respecta a rendimiento para salir de dudas he realizado un pequeño test, donde he obtenido todas las rutas absolutas de mi sistema de archivos, y estos han sido los resultados:

Como se puede comprobar, el archivo resultante Xml ocupa unos MB más que el binario, y también tarda más en cargar. Los nombres de los métodos tienen nombres self-explanatory, creo que no es necesario explicar su funcionalidad.

El código fuente parcial, en VB.Net:

( Para resumir lo que ocurre, simplemente obtengo la ruta absoluta de todos los archivos del disco duro "C:\", y seguidamente uso la class BinaryFormatter y XmlSerializer para serializar los datos, mientras que con un StopWatch mido el tiempo de ejecución de ambos tipos de serialización y deserialización. )
Código
  1. Imports System.IO
  2.  
  3. Public NotInheritable Class Form1 : Inherits Form
  4.  
  5.    Dim fileSystemPaths As String()
  6.    Const xmlFilePath As String = ".\FileSystem.xml"
  7.    Const binFilePath As String = ".\FileSystem.dat"
  8.  
  9.    Private Sub Form1_Shown() Handles MyBase.Shown
  10.  
  11.        Me.fileSystemPaths = Utils.FileDirSearcher.GetFilePaths("C:\", SearchOption.AllDirectories).ToArray
  12.  
  13.        Utils.Misc.MeasureAction(AddressOf SerializeXml, writeResultInConsole:=True)
  14.        Utils.Misc.MeasureAction(AddressOf SerializeBin, writeResultInConsole:=True)
  15.  
  16.        Utils.Misc.MeasureAction(AddressOf DeserializeXml, writeResultInConsole:=True)
  17.        Utils.Misc.MeasureAction(AddressOf DeserializeBin, writeResultInConsole:=True)
  18.  
  19.        Dim sb As New StringBuilder
  20.        With sb
  21.            .AppendLine(String.Format("Total file amount......: {0} files.", Me.fileSystemPaths.Count.ToString("n0")))
  22.            .AppendLine(String.Format("FileSystem.Xml filesize: {0} MB.", (New FileInfo(xmlFilePath).Length / (1024 * 1024)).ToString("n2")))
  23.            .AppendLine(String.Format("FileSystem.Dat filesize: {0} MB.", (New FileInfo(binFilePath).Length / (1024 * 1024)).ToString("n2")))
  24.        End With
  25.  
  26.        Console.WriteLine(sb.ToString)
  27.  
  28.    End Sub
  29.  
  30.    Private Sub SerializeXml()
  31.        Utils.SerializationUtil.Serialize(Me.fileSystemPaths, xmlFilePath, SerializationFormat.Xml)
  32.    End Sub
  33.  
  34.    Private Sub SerializeBin()
  35.        Utils.SerializationUtil.Serialize(Me.fileSystemPaths, binFilePath, SerializationFormat.Binary)
  36.    End Sub
  37.  
  38.    Private Sub DeserializeXml()
  39.        Dim fileSystemFromXml As String() = Utils.SerializationUtil.Deserialize(Of String())(xmlFilePath, SerializationFormat.Xml)
  40.    End Sub
  41.  
  42.    Private Sub DeserializeBin()
  43.        Dim fileSystemFromBin As String() = Utils.SerializationUtil.Deserialize(Of String())(binFilePath, SerializationFormat.Binary)
  44.    End Sub
  45.  
  46. End Class

El código fuente de la solución completa:
http://www.mediafire.com/download/u167fme23z6p5ju/WindowsApplication1.rar

PD: C# y VB.Net son dos lenguajes (casi)idénticos internamente hablando, ya que ambos forman parte de la plataforma .Net, compilan mediante el CIL de Microsoft y se administra u optimiza mediante el JIT/NGen, así que podemos asumir que el test es igual de válido para dicho lenguaje, por si alguien tenía dudas.

Saludos.
Hola!

He estado revisando mi código y es similar al que tengo yo (formato XML).

Me gusta el rendimiento y el tamaño del fichero binario pero he sido incapaz de leerlo con VB6.
He leído por ahi que con VB6 no es posible deserializar binarios.
Hasta que no encuentre una solución me quedaré con el XML normal.

¿Sería interesante que compartiera mi código, lo veo tan simple?

Enviado desde mi GT-I9300 mediante Tapatalk
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Editar y guardar ficheros [Solucionado]
PHP
i-Charlie 7 5,445 Último mensaje 8 Octubre 2009, 19:45 pm
por дٳŦ٭
¿Cómo crear,consultar y guardar ficheros en GUI? (JAVA) « 1 2 3 »
Java
the walrus 23 20,959 Último mensaje 5 Marzo 2010, 18:55 pm
por Leyer
Guardar variables en ficheros C
Programación C/C++
nyper01 5 3,244 Último mensaje 16 Diciembre 2013, 20:45 pm
por xiruko
guardar estructuras en ficheros
Programación C/C++
pedroedlp 6 3,809 Último mensaje 23 Abril 2014, 19:24 pm
por pedroedlp
¿Como obtener una combinacion mediante su indice?
Scripting
Yidu 9 4,756 Último mensaje 19 Julio 2015, 12:02 pm
por Yidu
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines