Entrada destacada

¿Cual es mejor? ¿una Pc Clon o una Pc de Marca?

¿Que es Pc Clon? Es una Pc Armada con varias parte de otros fabricantes, permitiendo organizar de forma independiente el procesamien...

Ultimas entradas

Entradas populares

You are here

Autodetector de separadores en archivos CSV


Introducción

Los archivos CSV son muy populares para almacenar datos tabulares porque son archivos de texto simples con muy pocas reglas. Esto los hace muy interoperables ya que tanto escritores como lectores CSV son relativamente fáciles de implementar. La interoperabilidad es, probablemente, la primera razón por qué alguien elegiría para guardar los datos en formato CSV.

Aunque las reglas para escribir y leer archivos CSV, son relativamente conocidas y ampliamente aceptadas, una regla es una excepción. La determinación de un carácter que se utilizará como separador. Archivos CSV, como los valores de separados por comas, deben utilizar [,] coma como separador, pero hay muchos archivos CSV que utilizan punto y coma [;] o tabulación horizontal [\t] como separador.

Por lo tanto, a fin de construir lector CSV genérico que leerá el archivo CSV independientemente del separador, el  lector debe primero averiguar qué carácter se utiliza como separador. Este artículo proporciona una posible solución a este problema.


Formato CSV

Las reglas para escribir archivos CSV son bastante simples:

·         Si valor contiene el carácter separador o carácter de nueva línea o comienza con una cita: escriba el valor entre comillas.

·         Si el valor está entre comillas: cualquier carácter de oferta contenida en el valor debe ser seguida de un carácter adicional.

Estas dos reglas simples permiten escribir fácilmente, escritores CSV en pocos minutos. La aplicación del Lector de  CSV es mucho más problemático porque la secuencia CSV tiene que analizarse secuencialmente, carácter por carácter y el almacenamiento de información de estado adicional debe proporcionarse – que efectivamente hace lector CSV una máquina de Estado. Hay un montón de lectores CSV por ahí que tienen aplicación errónea porque no siguen las reglas indicadas.


Implementación


Ahora que hemos definido las reglas de archivos CSV, podemos implementar un lector CSV que sea capaz de averiguar qué carácter se utiliza como separador.

Aquí el código fuente C# del método que detecta separador en secuencia CSV:



public static char Detect(TextReader reader, int rowCount, IList<char> separators)
{
    IList<int> separatorsCount = new int[separators.Count];

    int character;

    int row = 0;

    bool quoted = false;
    bool firstChar = true;

    while (row < rowCount)
    {
        character = reader.Read();

        switch (character)
        {
            case '"':
                if (quoted)
                {
                    if (reader.Peek() != '"') // Value is quoted and current character is " and next character is not ".
                        quoted = false;
                    else
                        reader.Read(); // Value is quoted and current and next characters are "" - read (skip) peeked qoute.
                }
                else
                {
                    if (firstChar) // Set value as quoted only if this quote is the first char in the value.
                        quoted = true;
                }
                break;
            case '\n':
                if (!quoted)
                {
                    ++row;
                    firstChar = true;
                    continue;
                }
                break;
            case -1:
                row = rowCount;
                break;
            default:
                if (!quoted)
                {
                    int index = separators.IndexOf((char)character);
                    if (index != -1)
                    {
                        ++separatorsCount[index];
                        firstChar = true;
                        continue;
                    }
                }
                break;
        }

        if (firstChar)
            firstChar = false;
    }

    int maxCount = separatorsCount.Max();

    return maxCount == 0 ? '\0' : separators[separatorsCount.IndexOf(maxCount)];
}


La seecuencia CSV está representada con parámetro de lector que se utiliza para leer caracteres de la secuencia de la CSV, el parámetro rowCount indica el método de  cuántas filas se deben leer antes de determinar el separador y el parámetro Separators es una lista de caracteres que indica el método de que caracteres son posibles separadores.

El método mantiene estado interno con estos parámetros:

separatorsCount: utilizada para contar el número de apariciones posibles del separador, como separador en secuencia de CSV

carácter:  último carácter que se lee de la secuencia de la CSV.

row: índice de fila actual en proceso, en la secuencia de la CSV.

Quoted:  true si los caracteres que se leen a continuación están entre comillas, false en caso contrario.

firstChar:  true si el siguiente carácter que debe leerse es el primer carácter de la próxima entrada en secuencia CSV. Este parámetro es necesario porque consideramos un valor a ser entre comillas sólo si la cotización de apertura es el primer carácter de la entrada de la CSV.


Cuando se leen rowCount filas o secuencia CSV es leer hasta el final, el método devuelve primero de los separadores posibles que tiene un número máximo de veces como separador en secuencia CSV. Si cualquiera de los separadores posibles nunca se produjo como un separador en secuencia CSV, se devuelve '\0'.

El método se encarga al leer frases, separadores y nuevos caracteres de línea que forman parte del citado valor. En este caso, si se lee una cita, método peek Stream de CSV para ver si el siguiente carácter es también una cita, de lo contrario examinará esta cita como una quote de cierre. Nuevos caracteres de línea y el separador se omiten si figura en un valor entre comillas.

Por ejemplo, en el siguiente archivo Employees.csv:


Name,Surname,Salary
Juan,Perez,”$2,130″
Alberto;Martinez;”$1,500″
Emilio;Castro;”$1,650″
Juan;Rozzi;”$3,200″

El método detecta que el separador CSV es [;] aunque el  total número de apariciones del [;] es el 6 y el número total de ocurrencias de [,] es 8. Eso es porque la última 4 apariciones de [,] están entre comillas y estas no califican como un posible separadores. Por lo que el número total de ocurrencias de [,] como separadores es 4 y total el número de apariciones del [;] como separadores es 6, lo que hace separador CSV [;] la más probable.


Alternativa

 No debería ser demasiado difícil derivar todo lector CSV desde el código que figura en el presente artículo, pero los datos tabulares pueden venir en muchos formatos diferentes y aplicación de un lector y un escritor para cada uno de ellos puede no ser tan fácil y realmente podría afectar su productividad.

Por esa razón, se podría utilizar algún componente de terceros que soporta varios formatos de archivo. Esto probablemente le costará algo de dinero, pero formatos como XLS, XLSX, CSV, ODS, HTML es probable que se admitan dentro de la misma API, por lo que su aplicación será capaz de admitir formatos de archivo diferentes utilizando el mismo código de destino.

Christian Sanchez

We are.., This is a short description in the author block about the author. You edit it by entering text in the "Biographical Info" field in the user admin panel.

No hay comentarios:

Leave a Reply

Dejanos tu mensaje, a la brevedad te responderemos