Pregunta

¿Cuál sería el mejor enfoque para analizar un archivo delimitado cuando las columnas son desconocidos antes de analizar el archivo?

El formato de archivo es v3 Rightmove (.blm), las miradas estructura como esta:

#HEADER#
Version : 3
EOF : '^'
EOR : '~'
#DEFINITION#
AGENT_REF^ADDRESS_1^POSTCODE1^MEDIA_IMAGE_00~ // can be any number of columns
#DATA#
agent1^the address^the postcode^an image~
agent2^the address^the postcode^^~      // the records have to have the same number of columns as specified in the definition, however they can be empty
etc
#END#

Los archivos potencialmente puede ser muy grande, el archivo de ejemplo que tengo es 40Mb pero podrían ser varios cientos de megabytes. A continuación se muestra el código que había comenzado antes me di cuenta de las columnas eran dinámicos, estoy abriendo un filestream como leí que era la mejor manera de manejar archivos de gran tamaño. No estoy seguro de que mi idea de poner todos los registros en una lista entonces el procesamiento es bueno, sin embargo, no se sabe si eso va a trabajar con este tipo de archivos de gran tamaño.

List<string> recordList = new List<string>();

try
{
    using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
    {
        StreamReader file = new StreamReader(fs);
        string line;
        while ((line = file.ReadLine()) != null)
        {
            string[] records = line.Split('~');

            foreach (string item in records)
            {
                if (item != String.Empty)
                {
                    recordList.Add(item);
                }
            }

        }
    }
}
catch (FileNotFoundException ex)
{
    Console.WriteLine(ex.Message);
}

foreach (string r in recordList)
{
    Property property = new Property();

    string[] fields = r.Split('^');

    // can't do this as I don't know which field is the post code
    property.PostCode = fields[2];
    // etc

    propertyList.Add(property);
}

¿Alguna idea de cómo hacer esto mejor? Es C # 3.0 y .Net 3.5, si eso ayuda.

Gracias,

Annelie

¿Fue útil?

Solución

Si se puede despojar a cabo algunas de las líneas en la salida (el contenido de la cabecera, y el # líneas # xxx), entonces es simplemente un archivo CSV con ^ como delimitador, por lo que cualquier CSV clase lector hará el truco.

Otros consejos

Se puede hacer esto de varias maneras.

  1. Si las propiedades de los objetos tienen el mismo nombre que las columnas en el archivo de datos, se puede utilizar la reflexión para determinar qué columnas se deben emparejar a qué propiedades.
  2. Si las propiedades de los objetos tienen diferentes nombres, entonces se podría escribir un esquema de asignación personalizada que decir "para la columna X, asigne a la propiedad Y".
  3. Se puede crear atributos personalizados para sus propiedades de objetos que indican qué nombre de la columna que se asignan a, y la reflexión utilizar para leer esos atributos.

Todos estos pasos presuponen que los nombres de columna en los archivos de datos serán los mismos para los datos que representan (es decir, address_1 siempre será el nombre de la columna de datos de línea de dirección "uno").

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top