java.io -> java.nio
This commit is contained in:
parent
6126ed3c15
commit
70c607f2e8
|
@ -2,12 +2,14 @@ package schule.ngb.zm.util.io;
|
|||
|
||||
import schule.ngb.zm.util.Log;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
@ -23,19 +25,24 @@ public final class FileLoader {
|
|||
|
||||
public static final Charset ISO_8859_1 = StandardCharsets.ISO_8859_1;
|
||||
|
||||
|
||||
public static List<String> loadLines( String source ) {
|
||||
return loadLines(source, UTF8);
|
||||
}
|
||||
|
||||
public static List<String> loadLines( String source, Charset charset ) {
|
||||
try {
|
||||
return Files.readAllLines(Paths.get(ResourceStreamProvider.getResourceURL(source).toURI()), charset);
|
||||
} catch( IOException | URISyntaxException ex ) {
|
||||
LOG.error(ex, "Error while loading lines from source <%s>", source);
|
||||
}
|
||||
try( BufferedReader reader = ResourceStreamProvider.getReader(source, charset) ) {
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
return Collections.emptyList();
|
||||
String line;
|
||||
while( (line = reader.readLine()) != null ) {
|
||||
result.add(line);
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch( IOException ex ) {
|
||||
LOG.error(ex, "Error while loading lines from source <%s>", source);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
public static String loadText( String source ) {
|
||||
|
@ -43,61 +50,94 @@ public final class FileLoader {
|
|||
}
|
||||
|
||||
public static String loadText( String source, Charset charset ) {
|
||||
try {
|
||||
return Files.readString(Paths.get(ResourceStreamProvider.getResourceURL(source).toURI()), charset);
|
||||
} catch( IOException | URISyntaxException ex ) {
|
||||
LOG.error(ex, "Error while loading text from source <%s>", source);
|
||||
}
|
||||
try( BufferedReader reader = ResourceStreamProvider.getReader(source, charset) ) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
|
||||
return "";
|
||||
String line;
|
||||
while( (line = reader.readLine()) != null ) {
|
||||
result.append(line).append('\n');
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
} catch( IOException ex ) {
|
||||
LOG.error(ex, "Error while loading string from source <%s>", source);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static String[][] loadCsv( String source, boolean skipFirst ) {
|
||||
return loadCsv(source, ',', skipFirst, UTF8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt die Daten aus einer CSV Datei in ein zweidimensionales
|
||||
* String-Array.
|
||||
* <p>
|
||||
* Die Methode ist nicht in der Lage, komplexe CSV-Dateien zu verarbeiten.
|
||||
* Insbesondere können Inhalte, die das Trennzeichen {@code separator}
|
||||
* enthalten, nicht korrekt erkannt werden. Das Trennzeichen wird unabhängig
|
||||
* vom Kontext immer als Zelltrenner erkannt. (Im Normalfall kann das
|
||||
* Trennzeichen durch die Verwendung doppelter Anführungszeichen in der Art
|
||||
* {@code Inhalt,"Inhalt, der Komma enthält",Inhalt} maskiert werden.)
|
||||
* <p>
|
||||
* Es wird auch keine erweiterte Inhaltserkennung ausgeführt, sondern alle
|
||||
* Inhalte als {@code String} gelesen. Die weitere Verarbeitung mit den
|
||||
* passenden Parser-Methoden (beispielsweise
|
||||
* {@link Double#parseDouble(String)}) obligt dem Nutzer.
|
||||
*
|
||||
* @param source Die Quelle der CSV-Daten.
|
||||
* @param separator Das verwendete Trennzeichen.
|
||||
* @param skipFirst Ob die erste Zeile übersprungen werden soll.
|
||||
* @param charset Die zu verwendende Zeichenkodierung.
|
||||
* @return Ein Array mit den Daten als {@code String}s.
|
||||
*/
|
||||
public static String[][] loadCsv( String source, char separator, boolean skipFirst, Charset charset ) {
|
||||
try( Stream<String> lines = Files
|
||||
.lines(Paths.get(ResourceStreamProvider.getResourceURL(source).toURI()), charset)
|
||||
) {
|
||||
int n = skipFirst ? 1 : 0;
|
||||
return lines.skip(n).map(
|
||||
( line ) -> line.split(Character.toString(separator))
|
||||
).toArray(String[][]::new);
|
||||
} catch( IOException | URISyntaxException ex ) {
|
||||
LOG.error(ex, "Error while loading csv source <%s>", source);
|
||||
}
|
||||
|
||||
return new String[0][0];
|
||||
int n = skipFirst ? 1 : 0;
|
||||
List<String> lines = loadLines(source, charset);
|
||||
return lines.stream().skip(n).map(
|
||||
//( line ) -> line.split(Character.toString(separator))
|
||||
( line ) -> line.split("\\s*" + separator + "\\s*")
|
||||
).toArray(String[][]::new);
|
||||
}
|
||||
|
||||
public static double[][] loadValues( String source, char separator, boolean skipFirst ) {
|
||||
return loadValues(source, separator, skipFirst, UTF8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt Double-Werte aus einer CSV Datei in ein zweidimensionales Array.
|
||||
* <p>
|
||||
* Die gelesenen Strings werden mit {@link Double#parseDouble(String)} in
|
||||
* {@code double} umgeformt. Es leigt in der Verantwortung des Nutzers
|
||||
* sicherzustellen, dass die CSV-Datei auch nur Zahlen enthält, die korrekt
|
||||
* in {@code double} umgewandelt werden können. Zellen für die die
|
||||
* Umwandlung fehlschlägt werden mit 0.0 befüllt.
|
||||
* <p>
|
||||
* Die Methode unterliegt denselben Einschränkungen wie
|
||||
* {@link #loadCsv(String, char, boolean, Charset)}.
|
||||
*
|
||||
* @param source Die Quelle der CSV-Daten.
|
||||
* @param separator Das verwendete Trennzeichen.
|
||||
* @param skipFirst Ob die erste Zeile übersprungen werden soll.
|
||||
* @param charset Die zu verwendende Zeichenkodierung.
|
||||
* @return Ein Array mit den Daten als {@code String}s.
|
||||
*/
|
||||
public static double[][] loadValues( String source, char separator, boolean skipFirst, Charset charset ) {
|
||||
try( Stream<String> lines = Files
|
||||
.lines(Paths.get(ResourceStreamProvider.getResourceURL(source).toURI()), charset)
|
||||
) {
|
||||
int n = skipFirst ? 1 : 0;
|
||||
return lines.skip(n).map(
|
||||
( line ) -> Arrays
|
||||
.stream(line.split(Character.toString(separator)))
|
||||
.mapToDouble(
|
||||
( value ) -> {
|
||||
try {
|
||||
return Double.parseDouble(value);
|
||||
} catch( NumberFormatException nfe ) {
|
||||
return 0.0;
|
||||
}
|
||||
int n = skipFirst ? 1 : 0;
|
||||
List<String> lines = loadLines(source, charset);
|
||||
return lines.stream().skip(n).map(
|
||||
( line ) -> Arrays
|
||||
.stream(line.split(Character.toString(separator)))
|
||||
.mapToDouble(
|
||||
( value ) -> {
|
||||
try {
|
||||
return Double.parseDouble(value);
|
||||
} catch( NumberFormatException nfe ) {
|
||||
return 0.0;
|
||||
}
|
||||
).toArray()
|
||||
).toArray(double[][]::new);
|
||||
} catch( IOException | URISyntaxException ex ) {
|
||||
LOG.error(ex, "Error while loading double values from csv source <%s>", source);
|
||||
}
|
||||
|
||||
return new double[0][0];
|
||||
}
|
||||
).toArray()
|
||||
).toArray(double[][]::new);
|
||||
}
|
||||
|
||||
public FileLoader() {
|
||||
|
|
|
@ -5,13 +5,66 @@ import schule.ngb.zm.util.Log;
|
|||
import schule.ngb.zm.util.Validator;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* Helferklasse, um {@link InputStream}s für Resourcen zu erhalten.
|
||||
*/
|
||||
public class ResourceStreamProvider {
|
||||
|
||||
|
||||
/**
|
||||
* Ermittelt zur angegebenen Quelle einen passenden {@link URL} (<em>Unified
|
||||
* Resource Locator</em>). Eine passende Datei-Resource wird wie folgt
|
||||
* ermittelt:
|
||||
* <ol>
|
||||
* <li>Ist {@code source} eine existierende Datei
|
||||
* ({@code new File(source}.isFile() == true})?</li>
|
||||
* <li>Ist {@code source} ein relativer Pfad im Projekt ({@code getResource(source) != null})?.</li>
|
||||
* <li>Ist {@code source} im Classpath enthalten ({@code getClassLoader().getResource(source) != null})?</li>
|
||||
* <li>Ansonten erstellt ein {@link URL}-Objekt.</li>
|
||||
* </ol>
|
||||
* <p>
|
||||
* Ein {@code URL} für die erste gefundene Resource wird zurückgegeben.
|
||||
* Auftretende Exceptions
|
||||
* werden als {@link IOException} geworfen.
|
||||
* <p>
|
||||
* Bei einer Exception werden die folgenden Quellen nicht mehr abgefragt.
|
||||
* Eine {@link java.net.MalformedURLException} beim Konstruieren des {@code URL}
|
||||
* zu einer Datei verhindert daher, dass noch im Classpath gesucht wird.
|
||||
*
|
||||
* @param source Eine Quelle für die Resource (Absoluter Dateipfad,
|
||||
* Dateipfad im Classpath oder Netzwerkresource)
|
||||
* @return Ein {@code InputStream} für die Resource
|
||||
* @throws NullPointerException Falls {@code source} {@code null} ist.
|
||||
* @throws IllegalArgumentException Falls {@code source} ein leerer String
|
||||
* ist.
|
||||
* @throws IOException Geworfen beim Erzeugen einer URL zu
|
||||
* einer bestehenden Resource.
|
||||
*/
|
||||
public static URL getResourceURL( String source ) throws NullPointerException, IllegalArgumentException, IOException {
|
||||
Validator.requireNotNull(source, "Resource source may not be null");
|
||||
Validator.requireNotEmpty(source, "Resource source may not be empty.");
|
||||
|
||||
// Ist source ein valider Dateipfad?
|
||||
File file = new File(source);
|
||||
if( file.isFile() ) {
|
||||
return file.toURI().toURL();
|
||||
}
|
||||
// Ist source im Classpath vorhanden?
|
||||
URL url = Zeichenmaschine.class.getClassLoader().getResource(source);
|
||||
if( url != null ) {
|
||||
return url;
|
||||
}
|
||||
// Dann versuchen aus source direkt eine URL zu machen.
|
||||
return new URL(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sucht eine zur angegebenen Quelle passende Resource und öffnet einen
|
||||
* passenden {@link InputStream}. Die konkrete Art des Streams hängt davon
|
||||
|
@ -45,134 +98,41 @@ public class ResourceStreamProvider {
|
|||
* @throws NullPointerException Falls {@code source} {@code null} ist.
|
||||
* @throws IllegalArgumentException Falls {@code source} ein leerer String
|
||||
* ist.
|
||||
* @throws IOException Geworfen beim öffnen des Streams zu
|
||||
* @throws IOException Geworfen beim Öffnen des Streams zu
|
||||
* einer bestehenden Resource oder falls
|
||||
* keine passende Resource gefunden wurde.
|
||||
*/
|
||||
public static InputStream getInputStream( String source ) throws NullPointerException, IllegalArgumentException, IOException {
|
||||
Validator.requireNotNull(source, "Resource source may not be null");
|
||||
Validator.requireNotEmpty(source, "Resource source may not be empty.");
|
||||
|
||||
InputStream in = null;
|
||||
|
||||
// See if source is a readable file
|
||||
File file = new File(source);
|
||||
try {
|
||||
if( file.isFile() ) {
|
||||
in = new FileInputStream(file);
|
||||
}
|
||||
} catch( FileNotFoundException fnfex ) {
|
||||
// Somehow an exception occurred, but we still try other sources
|
||||
}
|
||||
// File does not exist, try other means
|
||||
// load ressource relative to .class-file
|
||||
if( in == null ) {
|
||||
in = Zeichenmaschine.class.getResourceAsStream(source);
|
||||
}
|
||||
|
||||
// relative to ClassLoader
|
||||
if( in == null ) {
|
||||
in = Zeichenmaschine.class.getClassLoader().getResourceAsStream(source);
|
||||
}
|
||||
|
||||
// load form web or jar-file
|
||||
if( in == null ) {
|
||||
in = new URL(source).openStream();
|
||||
}
|
||||
|
||||
// One of the above got a valid Stream,
|
||||
// otherwise an Exception was thrown
|
||||
return in;
|
||||
}
|
||||
|
||||
public static InputStream getInputStream( File file ) throws IOException {
|
||||
Validator.requireNotNull(file, "Provided file can't be null.");
|
||||
return new FileInputStream(file);
|
||||
}
|
||||
|
||||
public static InputStream getInputStream( URL url ) throws IOException {
|
||||
Validator.requireNotNull(url, "Provided URL can't be null.");
|
||||
return url.openStream();
|
||||
return getResourceURL(source).openStream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ermittelt zur angegebenen Quelle einen passenden {@link URL} (<em>Unified
|
||||
* Resource Locator</em>). Eine passende Datei-Resource wird wie folgt
|
||||
* ermittelt:
|
||||
* <ol>
|
||||
* <li>Ist {@code source} eine existierende Datei
|
||||
* ({@code new File(source}.isFile() == true})?</li>
|
||||
* <li>Ist {@code source} ein relativer Pfad im Projekt ({@code getResource(source) != null})?.</li>
|
||||
* <li>Ist {@code source} im Classpath enthalten ({@code getClassLoader().getResource(source) != null})?</li>
|
||||
* <li>Ansonten erstellt ein {@link URL}-Objekt.</li>
|
||||
* </ol>
|
||||
* <p>
|
||||
* Ein {@code URL} für die erste gefundene Resource wird zurückgegeben.
|
||||
* Auftretende Exceptions
|
||||
* werden als {@link IOException} geworfen.
|
||||
* <p>
|
||||
* Bei einer Exception werden die folgenden Quellen nicht mehr abgefragt.
|
||||
* Eine {@link java.net.MalformedURLException} beim Konstruieren des {@code URL}
|
||||
* zu einer Datei verhindert daher, dass noch im Classpath gesucht wird.
|
||||
*
|
||||
* @param source Eine Quelle für die Resource (Absoluter Dateipfad,
|
||||
* Dateipfad im Classpath oder Netzwerkresource)
|
||||
* @return Ein {@code InputStream} für die Resource
|
||||
* @throws NullPointerException Falls {@code source} {@code null} ist.
|
||||
* @throws IllegalArgumentException Falls {@code source} ein leerer String
|
||||
* ist.
|
||||
* @throws IOException Geworfen beim erzeugen eines URL zu
|
||||
* einer bestehenden Resource.
|
||||
*/
|
||||
public static URL getResourceURL( String source ) throws NullPointerException, IllegalArgumentException, IOException {
|
||||
Validator.requireNotNull(source, "Resource source may not be null");
|
||||
Validator.requireNotEmpty(source, "Resource source may not be empty.");
|
||||
|
||||
File file = new File(source);
|
||||
if( file.isFile() ) {
|
||||
return file.toURI().toURL();
|
||||
}
|
||||
|
||||
URL url;
|
||||
|
||||
url = Zeichenmaschine.class.getResource(source);
|
||||
if( url != null ) {
|
||||
return url;
|
||||
}
|
||||
|
||||
url = Zeichenmaschine.class.getClassLoader().getResource(source);
|
||||
if( url != null ) {
|
||||
return url;
|
||||
}
|
||||
|
||||
return new URL(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ver
|
||||
*
|
||||
* @param source
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static OutputStream getOutputStream( String source ) throws IOException {
|
||||
Validator.requireNotNull(source, "Resource source may not be null");
|
||||
Validator.requireNotEmpty(source, "Resource source may not be empty.");
|
||||
URL url = getResourceURL(source);
|
||||
return getOutputStream(new File(url.getPath()));
|
||||
try {
|
||||
return Files.newOutputStream(Path.of(getResourceURL(source).toURI()));
|
||||
} catch( URISyntaxException ex ) {
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static OutputStream getOutputStream( File file ) throws IOException {
|
||||
Validator.requireNotNull(file, "Provided file can't be null.");
|
||||
return new FileOutputStream(file);
|
||||
public static BufferedReader getReader( String source ) throws IOException {
|
||||
return getReader(source, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
public static Reader getReader( String source ) throws IOException {
|
||||
return new InputStreamReader(getInputStream(source));
|
||||
public static BufferedReader getReader( String source, Charset charset ) throws IOException {
|
||||
return new BufferedReader(new InputStreamReader(getInputStream(source), charset.newDecoder()));
|
||||
}
|
||||
|
||||
public static Writer getWriter( String source ) throws IOException {
|
||||
return new OutputStreamWriter(getOutputStream(source));
|
||||
public static BufferedWriter getWriter( String source ) throws IOException {
|
||||
return getWriter(source, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
public static BufferedWriter getWriter( String source, Charset charset ) throws IOException {
|
||||
return new BufferedWriter(new OutputStreamWriter(getOutputStream(source), charset.newEncoder()));
|
||||
}
|
||||
|
||||
private ResourceStreamProvider() {
|
||||
|
|
Loading…
Reference in New Issue