From 114fc31be09097aa64dd538fb89f222da201518a Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Sat, 1 May 2021 01:36:38 +0200 Subject: [PATCH] KmzImporter: process doc.kml as stream (instead of in memory copy). Also simplified exception handling. --- .../io/file/importer/KmzTrackImporter.java | 40 +++++-------------- .../io/file/importer/XMLImporter.java | 5 +++ 2 files changed, 16 insertions(+), 29 deletions(-) diff --git a/src/main/java/de/dennisguse/opentracks/io/file/importer/KmzTrackImporter.java b/src/main/java/de/dennisguse/opentracks/io/file/importer/KmzTrackImporter.java index 1b2386139..7f0063e2d 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/importer/KmzTrackImporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/importer/KmzTrackImporter.java @@ -22,10 +22,9 @@ import android.util.Log; import androidx.annotation.NonNull; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; +import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -52,8 +51,6 @@ public class KmzTrackImporter { private static final List KMZ_IMAGES_EXT = Arrays.asList("jpeg", "jpg", "png"); - private static final int BUFFER_SIZE = 4096; - private Context context; @NonNull @@ -207,33 +204,17 @@ public class KmzTrackImporter { } } - private List parseKml(ZipInputStream zipInputStream) { + private List parseKml(ZipInputStream zipInputStream) throws IOException { XMLImporter kmlFileTrackImporter = new XMLImporter(new KmlFileTrackImporter(context)); - try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(getKml(zipInputStream))) { - return kmlFileTrackImporter.importFile(byteArrayInputStream); - } catch (ImportParserException | ImportAlreadyExistsException e) { - throw e; - } catch (Exception e) { - throw new ImportParserException(e); - } - } - - /** - * Gets the kml as byte array. - * - * @param zipInputStream the zip input stream - */ - //TODO We should be able to process the stream; we are wasting memory here. - private byte[] getKml(ZipInputStream zipInputStream) throws IOException { - try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) { - byte[] buffer = new byte[BUFFER_SIZE]; - int count; - while ((count = zipInputStream.read(buffer)) != -1) { - byteArrayOutputStream.write(buffer, 0, count); + InputStream nonClosableInputStream = new FilterInputStream(zipInputStream) { + @Override + public void close() { + // SAX2 always tries close InputStreams; but that would also close our ZIP file. } - return byteArrayOutputStream.toByteArray(); - } + }; + + return kmlFileTrackImporter.importFile(nonClosableInputStream); } /** @@ -243,6 +224,7 @@ public class KmzTrackImporter { * @param trackId the track's id which image belongs to. * @param fileName the file name */ + @Deprecated //TODO Use JDK9's inputStream.transferTo() instead of manual buffer private void readAndSaveImageFile(ZipInputStream zipInputStream, Track.Id trackId, String fileName) throws IOException { if (trackId == null || fileName.equals("")) { return; @@ -252,7 +234,7 @@ public class KmzTrackImporter { File file = new File(dir, fileName); try (FileOutputStream fileOutputStream = new FileOutputStream(file)) { - byte[] buffer = new byte[BUFFER_SIZE]; + byte[] buffer = new byte[4096]; int count; while ((count = zipInputStream.read(buffer)) != -1) { fileOutputStream.write(buffer, 0, count); diff --git a/src/main/java/de/dennisguse/opentracks/io/file/importer/XMLImporter.java b/src/main/java/de/dennisguse/opentracks/io/file/importer/XMLImporter.java index 6f1ef9fb3..8d60d88b6 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/importer/XMLImporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/importer/XMLImporter.java @@ -19,6 +19,11 @@ import javax.xml.parsers.SAXParserFactory; import de.dennisguse.opentracks.content.data.Track; +/** + * Uses SAX2 to parse XML files. + *

+ * NOTE: SAX2 always closes InputStreams after processing. + */ public class XMLImporter { private static final String TAG = XMLImporter.class.getSimpleName();