with - CSV analizando en Java-ejemplo de trabajo..?
outputstream csv java (10)
Básicamente necesitará leer el archivo línea por línea.
Luego tendrá que dividir cada línea por el delimitador, digamos una coma (CSV significa valores separados por comas), con
String[] strArr=line.split(",");
Esto lo convertirá en una serie de cadenas que luego podrá manipular, por ejemplo con
String name=strArr[0];
int yearOfBirth = Integer.valueOf(strArr[1]);
int monthOfBirth = Integer.valueOf(strArr[2]);
int dayOfBirth = Integer.valueOf(strArr[3]);
GregorianCalendar dob=new GregorianCalendar(yearOfBirth, monthOfBirth, dayOfBirth);
Student student=new Student(name, dob); //lets pretend you are creating instances of Student
Tendrá que hacer esto para cada línea, así que envuelva este código en un bucle while. (Si no conoce el delimitador, simplemente abra el archivo en un editor de texto).
Quiero escribir un programa para un proyecto de Java escolar para analizar algunos CSV que no conozco. Sé el tipo de datos de cada columna, aunque no conozco el delimitador.
El problema que ni siquiera sé marginalmente cómo solucionarlo es analizar la fecha o incluso las columnas de fecha y hora. Pueden estar en uno de los muchos formatos.
Encontré muchas bibliotecas pero no tengo ni idea de cuál es la mejor para mis necesidades: http://opencsv.sourceforge.net/ http://www.csvreader.com/java_csv.php http://supercsv.sourceforge.net/ http://flatpack.sourceforge.net/
El problema es que soy un principiante de java total. Me temo que ninguna de esas bibliotecas puede hacer lo que necesito o no puedo convencerlas de que lo hagan.
Apuesto a que hay mucha gente aquí que tiene un ejemplo de código que podría ayudarme a comenzar en poco tiempo para lo que necesito:
- Se divide automáticamente en columnas (delimitador desconocido, se conocen los tipos de columna)
- convertir a Columntype (debería hacer frente a $,%, etc.)
- convertir fechas a Java Fecha u Objetos de calendario
Sería bueno obtener tantos ejemplos de código como sea posible por correo electrónico.
¡Muchas gracias! COMO
Como mínimo, deberá conocer el delimitador de columna.
Es posible que desee echar un vistazo a esta especificación para CSV. Tenga en cuenta que no existe una especificación oficial reconocida.
Si no lo hace ahora, no será posible hacer el delimitador, por lo que tendrá que averiguarlo de alguna manera. Si puede hacer una inspección manual del archivo, debería poder ver rápidamente qué es y codificarlo en su programa. Si el delimitador puede variar, su única esperanza es poder deducir del formato de los datos conocidos. Cuando Excel importa archivos CSV, le permite al usuario elegir el delimitador y esta es una solución que también podría usar.
Escribir tu propio analizador es divertido, pero probablemente deberías echarle un vistazo a Open CSV . Proporciona numerosas formas de acceder al CSV y también permite generar CSV. Y se maneja los escapes correctamente. Como se mencionó en otra publicación, también hay una biblioteca de análisis de CSV en Apache Commons, pero esa aún no se ha publicado.
Estoy de acuerdo con @Brian Clapper. He usado SuperCSV como analizador aunque he tenido resultados mixtos. Disfruto de su versatilidad, pero hay algunas situaciones dentro de mis propios archivos csv para los que no he podido reconciliar "todavía". Tengo fe en este producto y lo recomendaría en general: me estoy perdiendo algo simple, sin duda, que estoy haciendo en mi propia implementación.
SuperCSV puede analizar las columnas en varios formatos, hacer ediciones en las columnas, etc. Vale la pena echar un vistazo. Tiene ejemplos también, y fácil de seguir.
La única limitación que tengo es capturar una columna ''vacía'' y analizarla en un entero o tal vez en blanco, etc. Estoy obteniendo errores de puntero nulo, pero javadocs sugiere que cada procesador de celdas verifique primero los nulos. Entonces, me estoy culpando primero, por ahora. :-)
De todos modos, echa un vistazo a SuperCSV. http://supercsv.sourceforge.net/
Hay un problema serio con el uso
String[] strArr=line.split(",");
para analizar los archivos CSV, y eso es porque puede haber comas dentro de los valores de los datos, y en ese caso debe citarlos e ignorar las comas entre comillas.
Hay una manera muy simple de analizar esto:
/**
* returns a row of values as a list
* returns null if you are past the end of the input stream
*/
public static List<String> parseLine(Reader r) throws Exception {
int ch = r.read();
while (ch == ''/r'') {
//ignore linefeed chars wherever, particularly just before end of file
ch = r.read();
}
if (ch<0) {
return null;
}
Vector<String> store = new Vector<String>();
StringBuffer curVal = new StringBuffer();
boolean inquotes = false;
boolean started = false;
while (ch>=0) {
if (inquotes) {
started=true;
if (ch == ''/"'') {
inquotes = false;
}
else {
curVal.append((char)ch);
}
}
else {
if (ch == ''/"'') {
inquotes = true;
if (started) {
// if this is the second quote in a value, add a quote
// this is for the double quote in the middle of a value
curVal.append(''/"'');
}
}
else if (ch == '','') {
store.add(curVal.toString());
curVal = new StringBuffer();
started = false;
}
else if (ch == ''/r'') {
//ignore LF characters
}
else if (ch == ''/n'') {
//end of a line, break out
break;
}
else {
curVal.append((char)ch);
}
}
ch = r.read();
}
store.add(curVal.toString());
return store;
}
Hay muchas ventajas para este enfoque. Tenga en cuenta que cada personaje se toca EXACTAMENTE una vez. No hay lectura anticipada, retroceso en el búfer, etc. No se busca al final de la línea, y luego se copia la línea antes de analizar. Este analizador funciona únicamente desde la secuencia y crea cada valor de cadena una vez. Funciona en las líneas de encabezado y en las líneas de datos, usted solo trata con la lista devuelta apropiada para eso. Le da un lector, por lo que la secuencia subyacente se ha convertido en caracteres utilizando cualquier codificación que elija. La transmisión puede provenir de cualquier fuente: un archivo, una publicación HTTP, una obtención HTTP y usted la analiza directamente. Este es un método estático, por lo que no hay ningún objeto para crear y configurar, y cuando esto vuelve, no hay memoria retenida.
Puede encontrar una discusión completa de este código, y por qué este enfoque es el preferido en la publicación de mi blog sobre el tema: La única clase que necesita para archivos CSV .
Le recomendaría que comience por separar su tarea en sus componentes.
- Leer datos de cadena de un CSV
- Convertir datos de cadena al formato apropiado
Una vez que lo haga, debería ser bastante trivial utilizar una de las bibliotecas a las que se vincula (lo que seguramente manejará la tarea número 1). Luego repita los valores devueltos y convierta / convierta cada valor de Cadena al valor que desee.
Si la pregunta es cómo convertir cadenas en objetos diferentes, dependerá del formato con el que empieces y del formato con el que quieras terminar.
DateFormat.parse (), por ejemplo, analizará las fechas de las cadenas. Consulte SimpleDateFormat para construir rápidamente un DateFormat para una determinada representación de cadena. Integer.parseInt () compilará enteros a partir de cadenas.
Moneda, tendrás que decidir cómo quieres capturarla. Si solo desea capturar como un flotador, entonces Float.parseFloat () hará el truco (solo use String.replace () para eliminar todos los $ y comas antes de analizarlo). O puede analizar en BigDecimal (por lo que no tiene problemas de redondeo). Puede haber una mejor clase para el manejo de divisas (no hago mucho de eso, así que no estoy familiarizado con esa área del JDK).
Mi enfoque no sería comenzar escribiendo su propia API. La vida es demasiado corta y hay problemas más urgentes que resolver. En esta situación, típicamente:
- Encuentra una biblioteca que parece hacer lo que quiero. Si uno no existe, entonces implementarlo.
- Si existe una biblioteca, pero no estoy seguro de que sea adecuada para mis necesidades, escriba una API de adaptador delgado alrededor de ella, para poder controlar cómo se llama. La API del adaptador expresa la API que necesito y asigna esas llamadas a la API subyacente.
- Si la biblioteca no resulta adecuada, puedo intercambiar otra por debajo de la API del adaptador (ya sea otra de código abierto o algo que yo mismo escriba) con un mínimo de esfuerzo, sin afectar a las personas que llaman.
Comience con algo que alguien ya ha escrito. Las probabilidades son, va a hacer lo que quieras. Siempre puedes escribir el tuyo más tarde, si es necesario. OpenCSV es un punto de partida tan bueno como cualquier otro.
También tiene la biblioteca CSV de Apache Commons , tal vez hace lo que necesita. Consulte la guía . Actualizado a la versión 1.1 en 2014-11.
Además, para la edición a prueba de errores, creo que tendrá que codificarlo usted mismo ... a través de SimpleDateFormat
puede elegir sus formatos y especificar varios tipos, si la Date
no es como ninguno de sus tipos de pre-pensamiento, no lo es. No es una fecha.
Tuve que usar un analizador csv hace unos 5 años. Parece que hay al menos dos estándares csv: http://en.wikipedia.org/wiki/Comma-separated_values y lo que Microsoft hace en Excel.
Encontré este libaray que come tanto: http://ostermiller.org/utils/CSV.html , pero afaik, no tiene forma de inferir qué tipo de datos eran las columnas.