Zoeken…


Invoering

Java I / O (invoer en uitvoer) wordt gebruikt om de invoer te verwerken en de uitvoer te produceren. Java gebruikt het concept van stream om de I / O-operatie snel te maken. Het pakket java.io bevat alle klassen die vereist zijn voor invoer- en uitvoerbewerkingen. Bestanden verwerken wordt ook gedaan in Java door Java I / O API.

Alle bytes lezen naar een byte []

Java 7 introduceerde de zeer nuttige klasse Bestanden

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

Een afbeelding uit een bestand lezen

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

...

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

Een byte [] naar een bestand schrijven

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

De meeste java.io-bestands-API's accepteren zowel String als File als argumenten, dus u kunt ze net zo goed gebruiken

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

Stream versus Writer / Reader API

Streams bieden de meest directe toegang tot de binaire inhoud, dus alle InputStream / OutputStream implementaties werken altijd op int en 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);
}

Er zijn enkele uitzonderingen, waarschijnlijk met name de PrintStream die de "mogelijkheid biedt om gemakkelijk representaties van verschillende gegevenswaarden af te drukken". Hiermee kunt u System.out gebruiken als een binaire InputStream en als tekstuele uitvoer met behulp van methoden zoals System.out.println() .

Sommige stream-implementaties werken ook als een interface voor inhoud op een hoger niveau, zoals Java-objecten (zie Serialisatie) of native typen, bijvoorbeeld DataOutputStream / DataInputStream .

Met de klassen Writer en Reader biedt Java ook een API voor expliciete tekenstromen. Hoewel de meeste toepassingen deze implementaties zullen baseren op streams, onthult de API voor tekenstreams geen methoden voor binaire inhoud.

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

Wanneer het nodig is om tekens in binaire gegevens te coderen (bijvoorbeeld wanneer u de klassen InputStreamWriter / OutputStreamWriter ), moet u een OutputStreamWriter opgeven als u niet afhankelijk wilt zijn van de standaardtekenset van het platform. Gebruik bij twijfel een Unicode-compatibele codering, bijvoorbeeld UTF-8 die op alle Java-platforms wordt ondersteund. Daarom moet u waarschijnlijk uit de buurt blijven van klassen zoals FileWriter en FileReader omdat deze altijd de standaardplatformset gebruiken. Een betere manier om toegang te krijgen tot bestanden met behulp van karakterstreams is dit:

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

Een van de meest gebruikte Reader 's is BufferedReader die een methode biedt om hele tekstregels van een andere lezer te lezen en is vermoedelijk de eenvoudigste manier om een tekenstroom regel voor regel te lezen:

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

Een heel bestand in één keer lezen

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

\ Z is het EOF-symbool (einde bestand). Indien ingesteld als scheidingsteken, leest de scanner de vulling totdat de EOF-vlag is bereikt.

Een bestand lezen met een scanner

Een bestand regel voor regel lezen

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

woord voor woord

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

en u kunt de delimeter ook wijzigen met de methode scanner.useDelimeter ()

Itereren over een map en filteren op bestandsextensie

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

Migreren van java.io.File naar Java 7 NIO (java.nio.file.Path)

In deze voorbeelden wordt ervan uitgegaan dat u al weet wat NIO van Java 7 in het algemeen is en dat u gewend bent om code te schrijven met java.io.File . Gebruik deze voorbeelden om snel meer NIO-centrische documentatie voor migratie te vinden.

NIO van Java 7 is veel meer, zoals geheugen toegewezen bestanden of het openen van een ZIP- of JAR-bestand met FileSystem . Deze voorbeelden zullen slechts een beperkt aantal basistoepassingen behandelen.

Als basisregel geldt dat als u gewend bent om een bestandssysteem te lezen / schrijven met een java.io.File instantiemethode, u deze als een statische methode vindt in java.nio.file.Files .

Wijs naar een pad

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

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

Paden ten opzichte van een ander pad

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

Bestand converteren van / naar pad voor gebruik met bibliotheken

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

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

Controleer of het bestand bestaat en verwijder het als dat zo is

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

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

Schrijf naar een bestand via een OutputStream

Er zijn verschillende manieren om vanuit NIO te schrijven en te lezen met NIO voor verschillende prestaties en geheugenbeperkingen, leesbaarheid en gebruiksscenario's, zoals FileChannel , Files.write(Path path, byte\[\] bytes, OpenOption... options) . .. In dit voorbeeld wordt alleen OutputStream behandeld, maar u wordt sterk aangemoedigd om meer te weten te komen over geheugen toegewezen bestanden en de verschillende statische methoden die beschikbaar zijn in 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));
    }
}

Herhalen van elk bestand in een map

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

Recursieve map iteratie

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

Bestand lezen / schrijven met FileInputStream / FileOutputStream

Schrijf naar een bestand 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();
}

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

Merk op dat sinds Java 1.7 de try-with-resources- instructie werd geïntroduceerd die de implementatie van lezen / schrijven veel eenvoudiger maakte:

Schrijf naar een bestand 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();
}

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

Lezen van een binair bestand

U kunt een binair bestand lezen met behulp van dit stukje code in alle recente versies van 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();

Als u Java 7 of hoger gebruikt, is er een eenvoudigere manier om de nio API :

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

Locking

Een bestand kan worden vergrendeld met de FileChannel API die kan worden verkregen van Input Output streams en readers

Voorbeeld met streams

// Open een bestandsstream FileInputStream ios = new FileInputStream (bestandsnaam);

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

Een bestand kopiëren met InputStream en OutputStream

We kunnen gegevens rechtstreeks van een bron naar een gegevensverzameling kopiëren met behulp van een lus. In dit voorbeeld lezen we gegevens van een InputStream en schrijven we tegelijkertijd naar een OutputStream. Als we klaar zijn met lezen en schrijven, moeten we de bron sluiten.

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

Een bestand lezen met Kanaal en Buffer

Channel gebruikt een Buffer om gegevens te lezen / schrijven. Een buffer is een container met een vaste grootte waarin we een gegevensblok tegelijk kunnen schrijven. Channel is een behoorlijk sneller dan stream-gebaseerde I / O.

Als u gegevens uit een bestand met Channel wilt lezen, moeten de volgende stappen worden uitgevoerd-

  1. We hebben een exemplaar van FileInputStream . FileInputStream heeft een methode met de naam getChannel() die een kanaal retourneert.
  2. Roep de methode getChannel() van FileInputStream aan en getChannel() Channel.
  3. Maak een ByteBuffer. ByteBuffer is een container met een vaste grootte van bytes.
  4. Kanaal heeft een leesmethode en we moeten een ByteBuffer leveren als argument voor deze leesmethode. ByteBuffer heeft twee modi - alleen-lezen stemming en alleen-schrijven stemming. We kunnen de modus wijzigen met de methode flip() . Buffer heeft een positie, limiet en capaciteit. Zodra een buffer met een vaste grootte is gemaakt, zijn de limiet en capaciteit hetzelfde als de grootte en begint de positie vanaf nul. Terwijl een buffer met gegevens wordt geschreven, neemt de positie geleidelijk toe. Modus veranderen betekent, de positie veranderen. Om gegevens vanaf het begin van een buffer te lezen, moeten we de positie op nul zetten. flip () methode verander de positie
  5. Wanneer we de leesmethode van het Channel aanroepen, vult deze de buffer met gegevens.
  6. Als we de gegevens van de ByteBuffer moeten lezen, moeten we de buffer omdraaien om de modus te wijzigen in alleen-lezen in de modus Alleen-lezen en dan gegevens van de buffer blijven lezen.
  7. Wanneer er geen gegevens meer zijn om te lezen, retourneert de methode read() van kanaal 0 of -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();
  }
 }
}

Een bestand kopiëren met Kanaal

We kunnen Channel om bestandsinhoud sneller te kopiëren. Om dit te doen, kunnen we de transferTo() methode van 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();
        }
    }
}

Een bestand lezen met BufferedInputStream

Bestand lezen met een BufferedInputStream over het algemeen sneller dan FileInputStream omdat het een interne buffer onderhoudt om bytes op te slaan die zijn gelezen uit de onderliggende invoerstroom.

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

    }
}

Een bestand schrijven met Kanaal en buffer

Om gegevens naar een bestand te schrijven met behulp van Channel , moeten de volgende stappen worden uitgevoerd:

  1. Eerst moeten we een object van FileOutputStream
  2. Koop FileChannel door de methode getChannel() roepen vanuit FileOutputStream
  3. Maak een ByteBuffer en vul deze met gegevens
  4. Dan moeten we de flip() -methode van de ByteBuffer en doorgeven als argument van de write() -methode van het FileChannel
  5. Als we klaar zijn met schrijven, moeten we de bron sluiten
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();
  }
 }
}  

Een bestand schrijven met PrintStream

We kunnen de klasse PrintStream gebruiken om een bestand te schrijven. Het heeft verschillende methoden waarmee u waarden voor gegevenstypen kunt afdrukken. println() methode println() voegt een nieuwe regel toe. Als we klaar zijn met afdrukken, moeten we de 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();
        }

    }
}

Herhaal dit over een map waarin submappen worden afgedrukt

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

Directories toevoegen

Om een nieuwe map te maken van een File instantie, moet u een van de volgende twee methoden gebruiken: mkdirs() of mkdir() .

  • mkdir() - Creëert de map met de naam van deze abstracte padnaam. ( bron )
  • mkdirs() - Maakt de map met de naam van deze abstracte padnaam, inclusief alle noodzakelijke maar niet-bestaande bovenliggende mappen. Merk op dat als deze bewerking mislukt, het mogelijk is gelukt om enkele van de benodigde bovenliggende mappen te maken. ( bron )

Opmerking: createNewFile() maakt geen nieuwe map alleen een bestand aan.

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

Standaarduitvoer / fout blokkeren of omleiden

Soms schrijft een slecht ontworpen bibliotheek van derden ongewenste diagnoses naar System.out of System.err streams. De aanbevolen oplossingen hiervoor zouden zijn om een betere bibliotheek te vinden of (in het geval van open source) het probleem op te lossen en een patch voor de ontwikkelaars bij te dragen.

Als de bovenstaande oplossingen niet haalbaar zijn, moet u overwegen de streams om te leiden.

Omleiding op de opdrachtregel

Op een UNIX-, Linux- of MacOSX-systeem kan vanuit de shell worden gedaan met > omleiding. Bijvoorbeeld:

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

De eerste leidt de standaarduitvoer en standaardfout om naar "/ dev / null", wat alles weggooit dat naar die streams is geschreven. De tweede omleiding van standaarduitvoer naar "out.log" en standaardfout naar "error.log".

(Raadpleeg de documentatie van de opdrachtshell die u gebruikt voor meer informatie over omleiding. Soortgelijke adviezen zijn van toepassing op Windows.)

Als alternatief kunt u de omleiding implementeren in een wrapper-script of batchbestand waarmee de Java-toepassing wordt gestart.

Omleiding binnen een Java-toepassing

Het is ook mogelijk om de streams binnen een Java-toepassing opnieuw te gebruiken met System.setOut() en System.setErr() . Het volgende fragment stuurt bijvoorbeeld standaarduitvoer en standaardfout naar 2 logboekbestanden:

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

Als u de uitvoer volledig wilt weggooien, kunt u een uitvoerstroom maken die naar een ongeldige bestandsdescriptor "schrijft". Dit komt functioneel overeen met schrijven naar "/ dev / null" op UNIX.

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

Let op: wees voorzichtig met hoe u setOut en setErr :

  1. De omleiding heeft gevolgen voor de hele JVM.
  2. Door dit te doen, neemt u de mogelijkheid van de gebruiker weg om de streams van de opdrachtregel om te leiden.

Toegang tot de inhoud van een ZIP-bestand

De FileSystem API van Java 7 maakt het mogelijk om vermeldingen van of naar een Zip-bestand te lezen en toe te voegen met behulp van de Java NIO file API op dezelfde manier als op een ander bestandssysteem.

Het FileSystem is een bron die na gebruik correct moet worden afgesloten, daarom moet het try-with-resources-blok worden gebruikt.

Lezen van een bestaand bestand

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

Een nieuw bestand maken

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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow