Buscar..


Introducción

La E / S de Java (entrada y salida) se utiliza para procesar la entrada y producir la salida. Java utiliza el concepto de flujo para agilizar la operación de E / S. El paquete java.io contiene todas las clases necesarias para las operaciones de entrada y salida. El manejo de archivos también se realiza en java mediante la API de E / S de Java.

Leyendo todos los bytes a un byte []

Java 7 introdujo la clase de archivos muy útil

Java SE 7
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.Path;

Path path = Paths.get("path/to/file");

try {
    byte[] data = Files.readAllBytes(path);
} catch(IOException e) {
    e.printStackTrace();
}

Leyendo una imagen de un archivo.

import java.awt.Image;
import javax.imageio.ImageIO;

...

try {
    Image img = ImageIO.read(new File("~/Desktop/cat.png"));
} catch (IOException e) {
    e.printStackTrace();
}

Escribir un byte [] a un archivo

Java SE 7
byte[] bytes = { 0x48, 0x65, 0x6c, 0x6c, 0x6f };

try(FileOutputStream stream = new FileOutputStream("Hello world.txt")) {
    stream.write(bytes);
} catch (IOException ioe) {
    // Handle I/O Exception
    ioe.printStackTrace();
}
Java SE 7
byte[] bytes = { 0x48, 0x65, 0x6c, 0x6c, 0x6f };

FileOutputStream stream = null;
try {
    stream = new FileOutputStream("Hello world.txt");
    stream.write(bytes);
} catch (IOException ioe) {
    // Handle I/O Exception
    ioe.printStackTrace();
} finally {
    if (stream != null) {
        try {
            stream.close();
        } catch (IOException ignored) {}
    }
}

La mayoría de las API de archivos java.io aceptan tanto String como File como argumentos, por lo que también podría usar

File file = new File("Hello world.txt");
FileOutputStream stream = new FileOutputStream(file);

Stream vs Writer / Reader API

Los flujos proporcionan el acceso más directo al contenido binario, por lo que cualquier implementación de InputStream / OutputStream siempre opera en int s y byte s.

// Read a single byte from the stream
int b = inputStream.read();
if (b >= 0) { // A negative value represents the end of the stream, normal values are in the range 0 - 255
    // Write the byte to another stream
    outputStream.write(b);
}

// Read a chunk
byte[] data = new byte[1024];
int nBytesRead = inputStream.read(data);
if (nBytesRead >= 0) { // A negative value represents end of stream
    // Write the chunk to another stream
    outputStream.write(data, 0, nBytesRead);
}

Hay algunas excepciones, probablemente la más notable, PrintStream que agrega la "capacidad de imprimir representaciones de varios valores de datos de manera conveniente". Esto permite utilizar System.out como InputStream binario y como salida textual utilizando métodos como System.out.println() .

Además, algunas implementaciones de flujo funcionan como una interfaz para contenidos de alto nivel, como objetos Java (consulte Serialización) o tipos nativos, por ejemplo, DataOutputStream / DataInputStream .

Con las clases Writer y Reader , Java también proporciona una API para flujos de caracteres explícitos. Aunque la mayoría de las aplicaciones basarán estas implementaciones en flujos, la API de flujo de caracteres no expone ningún método para contenido binario.

// This example uses the platform's default charset, see below
// for a better implementation.

Writer writer = new OutputStreamWriter(System.out);
writer.write("Hello world!");

Reader reader = new InputStreamReader(System.in);
char singleCharacter = reader.read();

Siempre que sea necesario codificar caracteres en datos binarios (por ejemplo, al usar las clases InputStreamWriter / OutputStreamWriter ), debe especificar un conjunto de caracteres si no desea depender del conjunto de caracteres predeterminado de la plataforma. En caso de duda, utilice una codificación compatible con Unicode, por ejemplo, UTF-8 que sea compatible con todas las plataformas Java. Por lo tanto, probablemente debería alejarse de clases como FileWriter y FileReader ya que siempre usan el conjunto de caracteres predeterminado de la plataforma. Una mejor manera de acceder a los archivos utilizando secuencias de caracteres es esta:

Charset myCharset = StandardCharsets.UTF_8;

Writer writer = new OutputStreamWriter( new FileOutputStream("test.txt"), myCharset );
writer.write('Ä');
writer.flush();
writer.close();

Reader reader = new InputStreamReader( new FileInputStream("test.txt"), myCharset );
char someUnicodeCharacter = reader.read();
reader.close();

Uno de los Reader s más utilizados es BufferedReader que proporciona un método para leer líneas enteras de texto de otro lector y es probablemente la forma más sencilla de leer una línea de caracteres en línea de secuencia:

// Read from baseReader, one line at a time
BufferedReader reader = new BufferedReader( baseReader );
String line;
while((line = reader.readLine()) != null) {
  // Remember: System.out is a stream, not a writer!
  System.out.println(line);
}

Leyendo un archivo completo a la vez

File f = new File(path);
String content = new Scanner(f).useDelimiter("\\Z").next();

\ Z es el símbolo EOF (fin de archivo). Cuando se establece como delimitador, el Escáner leerá el relleno hasta que se alcance el indicador EOF.

Leyendo un archivo con un escáner

Leyendo un archivo línea por línea

public class Main {

    public static void main(String[] args) {
        try {
            Scanner scanner = new Scanner(new File("example.txt"));
            while(scanner.hasNextLine())
            {
                String line = scanner.nextLine();
                //do stuff
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

palabra por palabra

public class Main {

    public static void main(String[] args) {
        try {
            Scanner scanner = new Scanner(new File("example.txt"));
            while(scanner.hasNext())
            {
                String line = scanner.next();
                //do stuff
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

y también puede cambiar el delimitador utilizando el método scanner.useDelimeter ()

Iterando sobre un directorio y filtrando por extensión de archivo

    public void iterateAndFilter() throws IOException {
        Path dir = Paths.get("C:/foo/bar");
        PathMatcher imageFileMatcher =
            FileSystems.getDefault().getPathMatcher(
                "regex:.*(?i:jpg|jpeg|png|gif|bmp|jpe|jfif)");

        try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir,
                entry -> imageFileMatcher.matches(entry.getFileName()))) {

            for (Path path : stream) {
                System.out.println(path.getFileName());
            }
        }
    }

Migración de java.io.File a Java 7 NIO (java.nio.file.Path)

Estos ejemplos asumen que ya sabes lo que es NIO de Java 7 en general, y estás acostumbrado a escribir código usando java.io.File . Utilice estos ejemplos como un medio para encontrar rápidamente más documentación centrada en NIO para la migración.

Hay mucho más en el NIO de Java 7, como los archivos asignados en memoria o la apertura de un archivo ZIP o JAR utilizando FileSystem . Estos ejemplos solo cubrirán un número limitado de casos de uso básicos.

Como regla básica, si está acostumbrado a realizar una operación de lectura / escritura del sistema de archivos utilizando un método de instancia java.io.File , lo encontrará como un método estático dentro de java.nio.file.Files .

Apuntar a un camino

// -> IO
File file = new File("io.txt");

// -> NIO
Path path = Paths.get("nio.txt");

Caminos relativos a otro camino.

// Forward slashes can be used in place of backslashes even on a Windows operating system
// -> IO
File folder = new File("C:/");
File fileInFolder = new File(folder, "io.txt");

// -> NIO
Path directory = Paths.get("C:/");
Path pathInDirectory = directory.resolve("nio.txt");

Convertir archivo de / a ruta para usar con bibliotecas

// -> IO to NIO
Path pathFromFile = new File("io.txt").toPath();

// -> NIO to IO
File fileFromPath = Paths.get("nio.txt").toFile();

Compruebe si el archivo existe y elimínelo si existe.

// -> IO
if (file.exists()) {
    boolean deleted = file.delete();
    if (!deleted) {
        throw new IOException("Unable to delete file");
    }
}

// -> NIO
Files.deleteIfExists(path);

Escribir en un archivo a través de un OutputStream

Hay varias formas de escribir y leer desde un archivo utilizando NIO para diferentes limitaciones de rendimiento y memoria, legibilidad y casos de uso, como FileChannel , Files.write(Path path, byte\[\] bytes, OpenOption... options) . .. En este ejemplo, solo se cubre OutputStream , pero se recomienda encarecidamente que conozca los archivos asignados en memoria y los diversos métodos estáticos disponibles en java.nio.file.Files .

List<String> lines = Arrays.asList(
        String.valueOf(Calendar.getInstance().getTimeInMillis()),
        "line one",
        "line two");

// -> IO
if (file.exists()) {
    // Note: Not atomic
    throw new IOException("File already exists");
}
try (FileOutputStream outputStream = new FileOutputStream(file)) {
    for (String line : lines) {
        outputStream.write((line + System.lineSeparator()).getBytes(StandardCharsets.UTF_8));
    }
}

// -> NIO
try (OutputStream outputStream = Files.newOutputStream(path, StandardOpenOption.CREATE_NEW)) {
    for (String line : lines) {
        outputStream.write((line + System.lineSeparator()).getBytes(StandardCharsets.UTF_8));
    }
}

Iterando en cada archivo dentro de una carpeta

// -> IO
for (File selectedFile : folder.listFiles()) {
    // Note: Depending on the number of files in the directory folder.listFiles() may take a long time to return
    System.out.println((selectedFile.isDirectory() ? "d" : "f") + " " + selectedFile.getAbsolutePath());
}

// -> NIO
Files.walkFileTree(directory, EnumSet.noneOf(FileVisitOption.class), 1, new SimpleFileVisitor<Path>() {
    @Override
    public FileVisitResult preVisitDirectory(Path selectedPath, BasicFileAttributes attrs) throws IOException {
        System.out.println("d " + selectedPath.toAbsolutePath());
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFile(Path selectedPath, BasicFileAttributes attrs) throws IOException {
        System.out.println("f " + selectedPath.toAbsolutePath());
        return FileVisitResult.CONTINUE;
    }
});

Iteración de la carpeta recursiva

// -> IO
recurseFolder(folder);

// -> NIO
// Note: Symbolic links are NOT followed unless explicitly passed as an argument to Files.walkFileTree
Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {
    @Override
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
        System.out.println("d " + selectedPath.toAbsolutePath());
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFile(Path selectedPath, BasicFileAttributes attrs) throws IOException {
        System.out.println("f " + selectedPath.toAbsolutePath());
        return FileVisitResult.CONTINUE;
    }
});


private static void recurseFolder(File folder) {
    for (File selectedFile : folder.listFiles()) {
        System.out.println((selectedFile.isDirectory() ? "d" : "f") + " " + selectedFile.getAbsolutePath());
        if (selectedFile.isDirectory()) {
            // Note: Symbolic links are followed
            recurseFolder(selectedFile);
        }
    }
}

Lectura / escritura de archivos usando FileInputStream / FileOutputStream

Escribir en un archivo test.txt:

String filepath ="C:\\test.txt";
FileOutputStream fos = null;
try {
      fos = new FileOutputStream(filepath);
      byte[] buffer = "This will be written in test.txt".getBytes();
      fos.write(buffer, 0, buffer.length);
      fos.close();
} catch (FileNotFoundException e) {
      e.printStackTrace();
} catch (IOException e) {
      e.printStackTrace();
} finally{
      if(fos != null)
        fos.close();
}

Leer del archivo test.txt:

String filepath ="C:\\test.txt";        
FileInputStream fis = null;
try {
   fis = new FileInputStream(filepath);
   int length = (int) new File(filepath).length();
   byte[] buffer = new byte[length];
   fis.read(buffer, 0, length);
} catch (FileNotFoundException e) {
     e.printStackTrace();
} catch (IOException e) {
     e.printStackTrace();
} finally{
   if(fis != null)
     fis.close();
}

Tenga en cuenta que desde Java 1.7 se introdujo la declaración try-with-resources lo que hizo que la implementación de la operación de lectura / escritura sea mucho más sencilla:

Escribir en un archivo test.txt:

String filepath ="C:\\test.txt";
try (FileOutputStream fos = new FileOutputStream(filepath)){
    byte[] buffer = "This will be written in test.txt".getBytes();
    fos.write(buffer, 0, buffer.length);
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

Leer del archivo test.txt:

String filepath ="C:\\test.txt";
try (FileInputStream fis = new FileInputStream(filepath)){
    int length = (int) new File(filepath).length();
    byte[] buffer = new byte[length];
    fis.read(buffer, 0, length);
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

Leyendo de un archivo binario

Puede leer un archivo binario utilizando este fragmento de código en todas las versiones recientes de Java:

Java SE 1.4
File file = new File("path_to_the_file");
byte[] data = new byte[(int) file.length()];
DataInputStream stream = new DataInputStream(new FileInputStream(file));
stream.readFully(data);
stream.close();

Si está utilizando Java 7 o posterior, hay una forma más sencilla de usar la nio API :

Java SE 7
Path path = Paths.get("path_to_the_file");
byte [] data = Files.readAllBytes(path);

Cierre

Un archivo puede ser bloqueado usando la API FileChannel que se puede adquirir de los streams y readers de Input Input.

Ejemplo con streams

// Abrir una secuencia de archivos FileInputStream ios = new FileInputStream (nombre de archivo);

    // get underlying channel
    FileChannel channel = ios.getChannel();

    /*
     * try to lock the file. true means whether the lock is shared or not i.e. multiple processes can acquire a
     * shared lock (for reading only) Using false with readable channel only will generate an exception. You should
     * use a writable channel (taken from FileOutputStream) when using false. tryLock will always return immediately
     */
    FileLock lock = channel.tryLock(0, Long.MAX_VALUE, true);

    if (lock == null) {
        System.out.println("Unable to acquire lock");
    } else {
        System.out.println("Lock acquired successfully");
    }

    // you can also use blocking call which will block until a lock is acquired.
    channel.lock();

    // Once you have completed desired operations of file. release the lock
    if (lock != null) {
        lock.release();
    }

    // close the file stream afterwards
    // Example with reader
    RandomAccessFile randomAccessFile = new RandomAccessFile(filename,  "rw");
    FileChannel channel = randomAccessFile.getChannel();
    //repeat the same steps as above but now you can use shared as true or false as the channel is in read write mode

Copiando un archivo usando InputStream y OutputStream

Podemos copiar directamente los datos de una fuente a un sumidero de datos utilizando un bucle. En este ejemplo, estamos leyendo datos de un InputStream y, al mismo tiempo, escribimos en un OutputStream. Una vez que hayamos terminado de leer y escribir, tenemos que cerrar el recurso.

public void copy(InputStream source, OutputStream destination) throws IOException {
    try {
        int c;
        while ((c = source.read()) != -1) {
            destination.write(c);
        }
    } finally {
        if (source != null) {
            source.close();
        }
        if (destination != null) {
            destination.close();
        }
    }
}

Leyendo un archivo usando Channel y Buffer

Channel utiliza un Buffer para leer / escribir datos. Un búfer es un contenedor de tamaño fijo donde podemos escribir un bloque de datos a la vez. Channel es bastante más rápido que la E / S basada en flujo.

Para leer los datos de un archivo usando Channel necesitamos los siguientes pasos:

  1. Necesitamos una instancia de FileInputStream . FileInputStream tiene un método llamado getChannel() que devuelve un canal.
  2. Llame al método getChannel() de FileInputStream y adquiera Channel.
  3. Crear un ByteBuffer. ByteBuffer es un contenedor de tamaño fijo de bytes.
  4. El canal tiene un método de lectura y tenemos que proporcionar un ByteBuffer como argumento para este método de lectura. ByteBuffer tiene dos modos: modo de solo lectura y modo de solo escritura. Podemos cambiar el modo usando el método de llamada flip() . El búfer tiene una posición, límite y capacidad. Una vez que se crea un búfer con un tamaño fijo, su límite y capacidad son los mismos que el tamaño y la posición comienza desde cero. Mientras se escribe un búfer con datos, su posición aumenta gradualmente. Cambio de modo significa, cambiando la posición. Para leer datos desde el principio de un búfer, tenemos que establecer la posición a cero. método flip () cambiar la posición
  5. Cuando llamamos al método de lectura del Channel , se llena el búfer usando datos.
  6. Si necesitamos leer los datos de ByteBuffer , debemos voltear el búfer para cambiar su modo de solo escritura al modo de solo lectura y luego seguir leyendo los datos del búfer.
  7. Cuando ya no hay datos para leer, el método de read() del canal devuelve 0 o -1.
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class FileChannelRead {
 
public static void main(String[] args) {
  
   File inputFile = new File("hello.txt");
  
   if (!inputFile.exists()) {
    System.out.println("The input file doesn't exit.");
    return;
   }

  try {
   FileInputStream fis = new FileInputStream(inputFile);
   FileChannel fileChannel = fis.getChannel();
   ByteBuffer buffer = ByteBuffer.allocate(1024);

   while (fileChannel.read(buffer) > 0) {
    buffer.flip();
    while (buffer.hasRemaining()) {
     byte b = buffer.get();
     System.out.print((char) b);
    }
    buffer.clear();
   }

   fileChannel.close();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}

Copiando un archivo usando el canal

Podemos usar el Channel para copiar el contenido del archivo más rápido. Para hacerlo, podemos usar el método transferTo() de FileChannel .

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;

public class FileCopier {
    
    public static void main(String[] args) {
        File sourceFile = new File("hello.txt");
        File sinkFile = new File("hello2.txt");
        copy(sourceFile, sinkFile);
    }

    public static void copy(File sourceFile, File destFile) {
        if (!sourceFile.exists() || !destFile.exists()) {
            System.out.println("Source or destination file doesn't exist");
            return;
        }


        try (FileChannel srcChannel = new FileInputStream(sourceFile).getChannel();
             FileChannel sinkChanel = new FileOutputStream(destFile).getChannel()) {

            srcChannel.transferTo(0, srcChannel.size(), sinkChanel);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Leyendo un archivo usando BufferedInputStream

La lectura de archivos utilizando un BufferedInputStream generalmente es más rápida que FileInputStream porque mantiene un búfer interno para almacenar bytes leídos desde la secuencia de entrada subyacente.

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;


public class FileReadingDemo {

    public static void main(String[] args) {
        String source = "hello.txt";
        
        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(source))) {
            byte data;
            while ((data = (byte) bis.read()) != -1) {
                System.out.println((char) data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

Escribiendo un archivo usando Channel y Buffer

Para escribir datos en un archivo usando Channel necesitamos los siguientes pasos:

  1. Primero, necesitamos obtener un objeto de FileOutputStream
  2. Adquiera FileChannel llamando al método getChannel() desde FileOutputStream
  3. Crea un ByteBuffer y luego llénalo con datos
  4. Luego tenemos que llamar al método flip() del ByteBuffer y pasarlo como un argumento del método write() del FileChannel
  5. Una vez que hayamos terminado de escribir, tenemos que cerrar el recurso.
import java.io.*;
import java.nio.*;
public class FileChannelWrite {

 public static void main(String[] args) {

  File outputFile = new File("hello.txt");
  String text = "I love Bangladesh.";

  try {
   FileOutputStream fos = new FileOutputStream(outputFile);
   FileChannel fileChannel = fos.getChannel();
   byte[] bytes = text.getBytes();
   ByteBuffer buffer = ByteBuffer.wrap(bytes);
   fileChannel.write(buffer);
   fileChannel.close();
  } catch (java.io.IOException e) {
   e.printStackTrace();
  }
 }
}  

Escribiendo un archivo usando PrintStream

Podemos usar la clase PrintStream para escribir un archivo. Tiene varios métodos que le permiten imprimir cualquier valor de tipo de datos. println() método println() agrega una nueva línea. Una vez que hayamos terminado de imprimir, tenemos que vaciar el PrintStream .

import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.time.LocalDate;

public class FileWritingDemo {
    public static void main(String[] args) {
        String destination = "file1.txt";

        try(PrintStream ps = new PrintStream(destination)){
            ps.println("Stackoverflow documentation seems fun.");
            ps.println();
            ps.println("I love Java!");
            ps.printf("Today is: %1$tm/%1$td/%1$tY", LocalDate.now());

            ps.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }
}

Iterar sobre un directorio de subdirectorios de impresión en él.

  public void iterate(final String dirPath) throws IOException {
    final DirectoryStream<Path> paths = Files.newDirectoryStream(Paths.get(dirPath));
    for (final Path path : paths) {
      if (Files.isDirectory(path)) {
        System.out.println(path.getFileName());
      }
    }
  }

Agregando Directorios

Para crear un nuevo directorio a partir de una instancia de un File , deberá utilizar uno de los dos métodos siguientes: mkdirs() o mkdir() .

  • mkdir() : crea el directorio nombrado por este nombre de ruta abstracto. ( fuente )
  • mkdirs() : crea el directorio nombrado por esta ruta de acceso abstracta, incluidos los directorios primarios necesarios pero no existentes. Tenga en cuenta que si esta operación falla, es posible que haya logrado crear algunos de los directorios principales necesarios. ( fuente )

Nota: createNewFile() no creará un nuevo directorio solo un archivo.

File singleDir = new File("C:/Users/SomeUser/Desktop/A New Folder/");
    
File multiDir = new File("C:/Users/SomeUser/Desktop/A New Folder 2/Another Folder/");

// assume that neither "A New Folder" or "A New Folder 2" exist

singleDir.createNewFile(); // will make a new file called "A New Folder.file"
singleDir.mkdir(); // will make the directory
singleDir.mkdirs(); // will make the directory

multiDir.createNewFile(); // will throw a IOException
multiDir.mkdir(); // will not work
multiDir.mkdirs(); // will make the directory

Bloqueo o redireccionamiento de salida / error estándar

A veces, una biblioteca de terceros mal diseñada escribirá diagnósticos no deseados en las System.err System.out o System.err . Las soluciones recomendadas para esto serían encontrar una mejor biblioteca o (en el caso de código abierto) solucionar el problema y contribuir con un parche para los desarrolladores.

Si las soluciones anteriores no son factibles, entonces debería considerar redirigir los flujos.

Redireccionamiento en la línea de comando.

En un sistema UNIX, Linux o MacOSX se puede hacer desde el shell usando > redirección. Por ejemplo:

$ java -jar app.jar arg1 arg2 > /dev/null 2>&1
$ java -jar app.jar arg1 arg2 > out.log 2> error.log

El primero redirige la salida estándar y el error estándar a "/ dev / null", que desecha todo lo escrito en esas secuencias. El segundo redirige la salida estándar a "out.log" y el error estándar a "error.log".

(Para obtener más información sobre la redirección, consulte la documentación del shell de comandos que está utilizando. Se aplican consejos similares a Windows).

Alternativamente, puede implementar la redirección en un script de envoltura o un archivo por lotes que inicie la aplicación Java.

Redirección dentro de una aplicación Java

También es posible redirigir las secuencias dentro de una aplicación Java usando System.setOut() y System.setErr() . Por ejemplo, el siguiente fragmento de código redirige la salida estándar y el error estándar a 2 archivos de registro:

System.setOut(new PrintStream(new FileOutputStream(new File("out.log"))));
System.setErr(new PrintStream(new FileOutputStream(new File("err.log"))));

Si desea deshacerse de la salida por completo, puede crear una secuencia de salida que "escribe" en un descriptor de archivo no válido. Esto es funcionalmente equivalente a escribir en "/ dev / null" en UNIX.

System.setOut(new PrintStream(new FileOutputStream(new FileDescriptor())));
System.setErr(new PrintStream(new FileOutputStream(new FileDescriptor())));

Precaución: tenga cuidado con el uso de setOut y setErr :

  1. La redirección afectará a toda la JVM.
  2. Al hacer esto, está quitando la capacidad del usuario para redirigir los flujos desde la línea de comandos.

Accediendo a los contenidos de un archivo ZIP.

La API del sistema de archivos de Java 7 permite leer y agregar entradas desde o hacia un archivo Zip usando la API del archivo NIO de Java de la misma manera que opera en cualquier otro sistema de archivos.

FileSystem es un recurso que debe cerrarse correctamente después de su uso, por lo tanto, debe usarse el bloque try-with-resources.

Leyendo de un archivo existente

Path pathToZip = Paths.get("path/to/file.zip");
try(FileSystem zipFs = FileSystems.newFileSystem(pathToZip, null)) {
  Path root = zipFs.getPath("/");
  ... //access the content of the zip file same as ordinary files
} catch(IOException ex) {
  ex.printStackTrace();
}

Creando un nuevo archivo

Map<String, String> env = new HashMap<>();  
env.put("create", "true"); //required for creating a new zip file
env.put("encoding", "UTF-8"); //optional: default is UTF-8
URI uri = URI.create("jar:file:/path/to/file.zip");
try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) {
  Path newFile = zipFs.getPath("/newFile.txt");
  //writing to file
  Files.write(newFile, "Hello world".getBytes());
} catch(IOException ex) {
  ex.printStackTrace();
}


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow