En Java, por supuesto. Estoy escribiendo un programa y ejecutándolo en un entorno Windows, pero necesito que la salida (.csv) se realice en formato Unix. ¿Alguna solución fácil? ¡Gracias!¿Hay alguna manera de hacer que la salida de PrintWriter sea en formato UNIX?
Respuesta
Por "formato Unix" ¿quiere decir usar "\ n" como el terminador de línea en lugar de "\ r \ n"? Simplemente configure la propiedad del sistema line.separator
antes de crear el PrintWriter.
Así como una demostración:
import java.io.*;
public class Test
{
public static void main(String[] args)
throws Exception // Just for simplicity
{
System.setProperty("line.separator", "xxx");
PrintWriter pw = new PrintWriter(System.out);
pw.println("foo");
pw.println("bar");
pw.flush();
}
}
Por supuesto que establece que para toda la JVM, que no es lo ideal, pero puede ser todo lo que sucede necesitar.
Excelente, gracias! – Monster
Suponiendo que el problema de formato que se refieren a es que los saltos de línea de Windows son de carro y avance de línea de retorno ("\r\n"
), mientras que los de Unix son salto de línea ("\n"
) solamente, la forma más fácil de asegurarse de que su archivo utiliza LF, y CRLF es para evitar println
y en su lugar usar print("\n")
para terminar líneas.
Así que en lugar de:
writer.println("foo,bar,88");
uso
writer.print("foo,bar,88\n");
Usted puede simplemente buscar en los archivos pertinentes para println
para asegurarse de que todos ellos captura.
La diferencia entre este enfoque y el de Jon Skeet es que el suyo es global, pero requiere menos cambios. Siempre y cuando esté seguro de que no le importa que todo en su programa vaya a utilizar \ n en su lugar o \ r \ n, simplemente establecer line.separator es probablemente más fácil. – Zarkonnen
Ah, ya veo. Excelente idea también Sin embargo, en mi caso (aunque debería haberlo especificado), estoy buscando un enfoque global. ¡Gracias! – Monster
Un programador paranoico se sincronizaría en el objeto de propiedades del sistema, al menos si diferentes Printwriters necesitan diferentes tipos de terminadores de línea.
public static PrintWriter createPrintWriter(OutputStreamWriter out, boolean autoflush){
Properties props = System.getProperties();
synchronized (props) {
Object old = null;
try {
old = props.setProperty("line.separator", "\n");
return new PrintWriter(out, autoflush);
} finally {
if(old != null) {
props.put("line.separator", old);
}
}
}
}
¿Cuál es el razonamiento aquí :)? –
Para asegurarse de que realmente obtendrá la propiedad que acaba de establecer, a menos que esté ejecutando en un subproceso, o siempre utilizará el mismo terminador de línea, y que nunca va a cambiar. – KarlP
Desafortunadamente, esto no impide que otro método cambie la propiedad simultáneamente sin usar este bloqueo. –
Para escribir un archivo con los finales de línea Unix, anulan println en una clase derivada de PrintStream, y el uso de impresión con \ n.
PrintWriter out = new PrintWriter("testFile") {
@Override
public void println() {
write('\n');
}
};
out.println("This file will always have unix line endings");
out.println(41);
out.close();
Esto evita tener que tocar ninguna println llamadas existentes que tiene en su código.
No, solo debe sobrescribir 'println()'. Todos los demás métodos de impresión (por ejemplo, 'println (String)', 'println (int)', etc. se documentan como impresión de datos y luego se llama a 'println()'. Además, debe sincronizar en la variable protegida 'lock' –
Punto justo, reemplazar println() es una mejor idea. He actualizado mi código. La llamada a 'write' maneja el bloqueo. –
Veo 2 opciones más que no afectan a todo el sistema ni conducen a los valores de concurrencia como configurar el lineSeparator
. También declararía una enumeración que representa los finales de línea.
enum LineEnding {
UNIX("\n"), DOS("\r\n");
private String lineSeparator;
LineEnding(String lineSeparator) {
this.lineSeparator = lineSeparator;
}
public String getLineSeparator() {
return lineSeparator;
}
}
Establecer la
lineSeperator
utilizando la reflexión.Debe crear una fábrica que encapsule el acceso utilizando reflejo para ocultar las partes internas de PrintWriter de los clientes. P.ej. código de cliente debe tener este aspecto:
PrintWriterFactory.newPrintWriter(someWriter, LineEnding.UNIX);
Mientras que la aplicación podría tener este aspecto:
public class PrintWriterFactory { private static final Field lineSeparatorField; static { try { lineSeparatorField = PrintWriter.class.getDeclaredField("lineSeparator"); lineSeparatorField.setAccessible(true); } catch (NoSuchFieldException e) { throw new IllegalStateException("java.io.PrintWriter implementation changed. Unable to determine lineSeparator field.", e); } } public static PrintWriter newPrintWriter(Writer writer, LineEnding lineEnding) { PrintWriter printWriter = new PrintWriter(writer); try { lineSeparatorField.set(printWriter, lineEnding.getLineSeparator()); } catch (IllegalAccessException e) { throw new IllegalStateException("Can't set line ending", e); } return printWriter; } }
PS: La fábrica no debe ser estática. Puede utilizar una interfaz y varias implementaciones si la implementación de
PrintWriter
cambia de un JDK a otro y, por lo tanto, debe usar otra estrategia de reflexión.Extender PrintStream y sobrescribir el método
println()
public class LineEndingPrintWriter extends PrintWriter { protected boolean autoFlush = false; private LineEnding lineEnding; public LineEndingPrintWriter(Writer out, LineEnding lineEnding) { this(out, false, lineEnding); } public LineEndingPrintWriter(Writer out, boolean autoFlush, LineEnding lineEnding) { super(out, autoFlush); this.autoFlush = autoFlush; this.lineEnding = lineEnding; } public LineEndingPrintWriter(OutputStream out, LineEnding lineEnding) { this(out, false, lineEnding); } public LineEndingPrintWriter(OutputStream out, boolean autoFlush, LineEnding lineEnding) { super(out, autoFlush); this.autoFlush = autoFlush; this.lineEnding = lineEnding; } protected void ensureOpen() throws IOException { if (out == null) throw new IOException("Stream closed"); } public void println() { // Method body taken from java.io.PrintWriter.println(); try { synchronized (lock) { ensureOpen(); out.write(lineEnding.getLineSeparator()); if (autoFlush) { out.flush(); } } } catch (InterruptedIOException e) { Thread.currentThread().interrupt(); } catch (IOException e) { setError(); } } }
- 1. ¿Hay alguna manera de hacer que UserControl sea inafocable?
- 2. ¿Hay alguna manera fácil de hacer que ScrollViewer sea "hinchable"?
- 3. ¿Hay alguna manera de hacer la asignación de servlets en eclipse IDE que no sea manualmente?
- 4. ¿Cómo hacer que Unix sea binario autónomo?
- 5. ¿Hay alguna manera fácil de hacer que la matriz anidada sea plana?
- 6. ¿Hay alguna manera de hacer que @section sea opcional con asp.net mvc Razor ViewEngine?
- 7. En Matplotlib, ¿hay alguna manera de conocer la lista de formato de salida disponible?
- 8. ¿Hay alguna solución para hacer que un miembro de la estructura sea de alguna manera "privado" en C?
- 9. ¿Hay alguna manera de hacer que el widget de texto Tkinter sea solo de lectura?
- 10. ¿Hay alguna manera de hacer que el proceso de doxigen código C no documentado sea automático?
- 11. ¿Hay alguna manera de hacer que un operador de comparación sea una variable?
- 12. ¿Hay alguna manera de hacer que el simulador de iPad sea más grande?
- 13. ¿Hay alguna manera de hacer que un DIV no sea seleccionable?
- 14. ¿Hay alguna manera de hacer que una variable TSQL sea constante?
- 15. ¿Hay alguna manera de borrar la salida NSLog?
- 16. ¿Hay alguna manera eficiente de hacer que la consulta de la base de datos de Android sea más rápida?
- 17. ¿Hay alguna forma de hacer que un bloque sea opcional en la plantilla de Django?
- 18. ¿Hay alguna manera de hacer que un ExecutorService funcione recursivamente?
- 19. ¿Hay alguna manera de hacer que gcc emita código binario sin formato?
- 20. ¿Hay alguna manera de hacer que Guice Grapher trabaje?
- 21. ¿Hay alguna manera de hacer que TFS se pueda enlazar?
- 22. ¿Cómo hacer que la salida de GCC sea stdout?
- 23. ¿Hay alguna manera de hacer que la unión de C# funcione de manera estática?
- 24. ¿Hay alguna manera de hacer que el tiempo de ejecución de Jruby sea interno en todas las cadenas?
- 25. ¿Hay alguna manera de hacer parciales de carga AngularJS al principio y no cuando sea necesario?
- 26. ¿Hay alguna manera de hacer que Fabric resuma los resultados en una serie de hosts?
- 27. ¿Hay alguna manera de hacer que un constructor solo sea visible para una clase padre en C#?
- 28. PHP. ¿Hay alguna manera de requerir que un parámetro de función sea una matriz?
- 29. ¿Hay alguna manera fácil en Python de esperar hasta que cierta condición sea verdadera?
- 30. ¿Hay alguna manera de hacer una verificación parcial en TFS?
¿Qué quiere decir con formato UNIX? Formato de final de línea? – jitter