Suche…


Einführung

Java I / O (Eingabe und Ausgabe) wird verwendet, um die Eingabe zu verarbeiten und die Ausgabe zu erzeugen. Java verwendet das Stream-Konzept, um den E / A-Vorgang schnell zu machen. Das Paket java.io enthält alle für Eingabe- und Ausgabeoperationen erforderlichen Klassen. Die Handhabung von Dateien erfolgt auch in Java über die Java I / O-API.

Lesen aller Bytes in ein Byte []

Java 7 führte die sehr nützliche Klasse Files ein

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();
}

Ein Bild aus einer Datei lesen

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

...

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

Ein Byte [] in eine Datei schreiben

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) {}
    }
}

Die meisten java.io-Datei-APIs akzeptieren sowohl String als auch File als Argumente. Daher können Sie dies auch tun

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

Stream vs Writer / Reader API

Streams bieten den direktesten Zugriff auf den binären Inhalt. OutputStream alle InputStream / OutputStream Implementierungen immer auf int s und byte OutputStream .

// 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);
}

Es gibt einige Ausnahmen, vor allem der PrintStream , der "die Möglichkeit PrintStream , Darstellungen verschiedener Datenwerte bequem zu drucken". Dies ermöglicht die Verwendung von System.out sowohl als binärer InputStream als auch als System.out.println() mit Methoden wie System.out.println() .

Einige Stream-Implementierungen funktionieren auch als Schnittstelle zu übergeordneten Inhalten wie Java-Objekten (siehe Serialisierung) oder DataOutputStream Typen, z. B. DataOutputStream / DataInputStream .

Mit den Klassen Writer und Reader bietet Java auch eine API für explizite Zeichenströme. Obwohl die meisten Anwendungen diese Implementierungen auf Streams stützen, stellt die Zeichenstrom-API keine Methoden für binären Inhalt bereit.

// 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();

Wenn Zeichen in binäre Daten codiert werden müssen (z. B. bei Verwendung der InputStreamWriter / OutputStreamWriter Klassen), sollten Sie einen Zeichensatz angeben, wenn Sie nicht vom Standardzeichensatz der Plattform abhängig sein möchten. Verwenden Sie im Zweifelsfall eine Unicode-kompatible Codierung, z. B. UTF-8, die auf allen Java-Plattformen unterstützt wird. Daher sollten Sie sich wahrscheinlich nicht an Klassen wie FileWriter und FileReader da diese immer den Standardplattformzeichensatz verwenden. Eine bessere Möglichkeit, mit Zeichenströmen auf Dateien zuzugreifen, ist folgende:

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();

Einer der am häufigsten verwendeten Reader ist BufferedReader der eine Methode zum Lesen ganzer Textzeilen von einem anderen Reader bietet und vermutlich der einfachste Weg ist, einen Zeichenstrom Zeile für Zeile zu lesen:

// 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);
}

Eine ganze Datei auf einmal lesen

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

\ Z ist das EOF-Symbol (Dateiende). Als Trennzeichen wird der Scanner die Füllung lesen, bis das EOF-Flag erreicht ist.

Eine Datei mit einem Scanner lesen

Eine Datei Zeile für Zeile lesen

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();
        }
    }
}

Wort für Wort

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();
        }
    }
}

Sie können das Delimeter auch mithilfe der scanner.useDelimeter () -Methode ändern

Durchlaufen eines Verzeichnisses und Filtern nach Dateierweiterung

    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());
            }
        }
    }

Migration von java.io.File zu Java 7 NIO (java.nio.file.Path)

In diesen Beispielen wird davon ausgegangen, dass Sie bereits wissen, was NIO von Java 7 generell ist, und Sie sind daran java.io.File mit java.io.File Code zu java.io.File . Anhand dieser Beispiele können Sie schnell weitere NIO-basierte Dokumentation für die Migration finden.

Das NIO von Java 7 bietet noch viel mehr, z. B. speicherzugeordnete Dateien oder das Öffnen einer ZIP- oder JAR-Datei mit FileSystem . Diese Beispiele behandeln nur eine begrenzte Anzahl grundlegender Anwendungsfälle.

Wenn Sie java.io.File eine Dateisystem-Lese- / Schreiboperation mit einer java.io.File Instanzmethode java.io.File , finden Sie sie als statische Methode in java.nio.file.Files .

Zeigen Sie auf einen Pfad

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

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

Pfade relativ zu einem anderen Pfad

// 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");

Konvertieren der Datei von / in den Pfad zur Verwendung mit Bibliotheken

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

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

Überprüfen Sie, ob die Datei vorhanden ist, und löschen Sie sie gegebenenfalls

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

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

Schreiben Sie über einen OutputStream in eine Datei

Es gibt mehrere Möglichkeiten, aus einer Datei mit NIO zu schreiben und zu lesen, um unterschiedliche Leistungs- und Speicherbeschränkungen, Lesbarkeit und Anwendungsfälle zu FileChannel , wie z. B. FileChannel , Files.write(Path path, byte\[\] bytes, OpenOption... options) . In diesem Beispiel wird nur OutputStream behandelt. Es wird jedoch dringend OutputStream , sich über speicherzugeordnete Dateien und die verschiedenen statischen Methoden zu java.nio.file.Files in java.nio.file.Files verfügbar 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));
    }
}

Iteration für jede Datei innerhalb eines Ordners

// -> 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;
    }
});

Rekursive Ordner-Iteration

// -> 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);
        }
    }
}

Datei lesen / schreiben mit FileInputStream / FileOutputStream

Schreiben Sie in eine Datei 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();
}

Lesen aus Datei 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();
}

Beachten Sie, dass seit Java 1.7 die try-with-resources- Anweisung eingeführt wurde, was die Implementierung der Lese- / Schreiboperation wesentlich vereinfacht:

Schreiben Sie in eine Datei 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();
}

Lesen aus Datei 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();
}

Lesen aus einer Binärdatei

Sie können eine Binärdatei mit diesem Code in allen aktuellen Java-Versionen lesen:

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();

Wenn Sie Java 7 oder höher verwenden, gibt es eine einfachere Möglichkeit, die nio API :

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

Sperren

Eine Datei kann mit dem gesperrten FileChannel - API , die von Input Output erworben werden kann streams und readers

Beispiel mit streams

// Öffnet einen Dateistream FileInputStream ios = new FileInputStream (Dateiname);

    // 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

Eine Datei mit InputStream und OutputStream kopieren

Wir können Daten mithilfe einer Schleife direkt von einer Quelle in eine Datensenke kopieren. In diesem Beispiel lesen wir Daten von einem InputStream und schreiben gleichzeitig in einen OutputStream. Sobald wir mit dem Lesen und Schreiben fertig sind, müssen wir die Ressource schließen.

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();
        }
    }
}

Eine Datei mit Channel und Buffer lesen

Channel verwendet einen Buffer zum Lesen / Schreiben von Daten. Ein Puffer ist ein Container mit fester Größe, in den wir einen Datenblock gleichzeitig schreiben können. Channel ist ziemlich schnell als Stream-basierte E / A.

Um Daten aus einer Datei mit Channel zu lesen, müssen Sie die folgenden Schritte ausführen:

  1. Wir benötigen eine Instanz von FileInputStream . FileInputStream hat eine Methode namens getChannel() die einen Channel zurückgibt.
  2. Rufen Sie die getChannel() Methode von FileInputStream auf und rufen Sie den Channel ab.
  3. Erstellen Sie einen ByteBuffer. ByteBuffer ist ein Container mit fester Größe.
  4. Channel hat eine Lesemethode und wir müssen ein ByteBuffer als Argument für diese Lesemethode angeben. ByteBuffer verfügt über zwei Modi: Nur-Lese-Stimmung und Nur-Lese-Stimmung. Wir können den Modus mit dem Aufruf der Methode flip() ändern. Puffer hat eine Position, ein Limit und eine Kapazität. Sobald ein Puffer mit fester Größe erstellt wurde, stimmen sein Limit und seine Kapazität mit der Größe überein und die Position beginnt bei Null. Während ein Puffer mit Daten geschrieben wird, nimmt seine Position allmählich zu. Ändern des Modus bedeutet, die Position zu ändern. Um Daten vom Anfang eines Puffers aus lesen zu können, müssen wir die Position auf Null setzen. Die Flip () - Methode ändert die Position
  5. Wenn wir die Lesemethode des Channel aufrufen, wird der Puffer mit Daten gefüllt.
  6. Wenn wir die Daten aus dem ByteBuffer lesen ByteBuffer , müssen wir den Puffer umdrehen, um seinen Modus in den Nur-Lese-Modus zu ändern, und nur dann den schreibgeschützten Modus verwenden.
  7. Wenn keine Daten mehr zu lesen sind, gibt die read() Methode des Kanals 0 oder -1 zurück.
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();
  }
 }
}

Eine Datei mit Channel kopieren

Wir können Channel dazu verwenden, Dateiinhalte schneller zu kopieren. Dazu können wir die transferTo() Methode von 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();
        }
    }
}

Eine Datei mit BufferedInputStream lesen

Das Lesen einer Datei mit einem BufferedInputStream Allgemeinen schneller als mit FileInputStream da ein interner Puffer zum Speichern der aus dem darunterliegenden Eingabestrom gelesenen Bytes verwaltet wird.

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();
        }

    }
}

Eine Datei mit Channel und Buffer schreiben

Um Daten mit Channel in eine Datei zu schreiben, müssen wir die folgenden Schritte ausführen:

  1. Zuerst müssen wir ein Objekt von FileOutputStream
  2. FileChannel , um die getChannel() Methode vom FileOutputStream
  3. Erstellen Sie einen ByteBuffer und füllen Sie ihn mit Daten
  4. Dann müssen wir die flip() -Methode des ByteBuffer und als Argument der write() -Methode des FileChannel
  5. Sobald wir mit dem Schreiben fertig sind, müssen wir die Ressource schließen
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();
  }
 }
}  

Eine Datei mit PrintStream schreiben

Wir können die PrintStream Klasse verwenden, um eine Datei zu schreiben. Es gibt mehrere Methoden, mit denen Sie beliebige Datentypwerte drucken können. println() -Methode fügt eine neue Zeile an. Sobald wir mit dem Drucken fertig sind, müssen wir den 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();
        }

    }
}

Durchlaufen Sie ein Verzeichnis, in dem Unterverzeichnisse zum Drucken gedruckt werden

  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());
      }
    }
  }

Verzeichnisse hinzufügen

Um ein neues Verzeichnis aus einer File Instanz zu mkdirs() müssen Sie eine der beiden Methoden verwenden: mkdirs() oder mkdir() .

  • mkdir() - Erstellt das durch diesen abstrakten Pfadnamen benannte Verzeichnis. ( Quelle )
  • mkdirs() - Erstellt das durch diesen abstrakten Pfadnamen benannte Verzeichnis, einschließlich aller erforderlichen, jedoch nicht vorhandenen übergeordneten Verzeichnisse. Wenn dieser Vorgang fehlschlägt, ist es möglicherweise gelungen, einige der erforderlichen übergeordneten Verzeichnisse zu erstellen. ( Quelle )

Hinweis: createNewFile() erstellt kein neues Verzeichnis, sondern nur eine Datei.

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

Standardausgabe / Fehler blockieren oder umleiten

Manchmal schreibt eine schlecht entworfene Bibliothek eines Drittanbieters unerwünschte Diagnosen in die Streams von System.out oder System.err . Die empfohlenen Lösungen für dieses Problem sind, entweder eine bessere Bibliothek zu finden oder (im Fall von Open Source) das Problem zu beheben und den Entwicklern einen Patch zur Verfügung zu stellen.

Wenn die oben genannten Lösungen nicht durchführbar sind, sollten Sie die Streams umleiten.

Umleitung in der Befehlszeile

Unter UNIX kann ein Linux- oder MacOSX-System von der Shell aus mit > Umleitung ausgeführt werden. Zum Beispiel:

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

Der erste leitet die Standardausgabe und den Standardfehler nach "/ dev / null" um, wodurch alles, was in diese Streams geschrieben wird, weggeworfen wird. Die zweite Version leitet die Standardausgabe in "out.log" und den Standardfehler in "error.log" um.

(Weitere Informationen zur Umleitung finden Sie in der Dokumentation der von Ihnen verwendeten Befehlsshell. Ähnliches gilt für Windows.)

Alternativ können Sie die Umleitung in einem Wrapper-Skript oder einer Batch-Datei implementieren, die die Java-Anwendung startet.

Umleitung innerhalb einer Java-Anwendung

Es ist auch möglich, die Streams innerhalb einer Java-Anwendung mithilfe von System.setOut() und System.setErr() . Das folgende Snippet leitet beispielsweise die Standardausgabe und den Standardfehler in zwei Protokolldateien um:

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

Wenn Sie die Ausgabe vollständig wegwerfen möchten, können Sie einen Ausgabestrom erstellen, der in einen ungültigen Dateideskriptor "schreibt". Dies entspricht funktional dem Schreiben in "/ dev / null" unter UNIX.

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

Achtung: setOut Sie vorsichtig, wie Sie setOut und setErr :

  1. Die Umleitung wirkt sich auf die gesamte JVM aus.
  2. Dadurch nehmen Sie dem Benutzer die Möglichkeit, die Streams von der Befehlszeile umzuleiten.

Auf den Inhalt einer ZIP-Datei zugreifen

Die FileSystem-API von Java 7 ermöglicht das Lesen und Hinzufügen von Einträgen aus oder zu einer Zip-Datei mithilfe der Java-NIO-Datei-API auf dieselbe Weise wie bei einem anderen Dateisystem.

Das Dateisystem ist eine Ressource, die nach der Verwendung ordnungsgemäß geschlossen werden sollte. Daher sollte der Try-with-Resources-Block verwendet werden.

Lesen aus einer vorhandenen Datei

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();
}

Neue Datei erstellen

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
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow