Skip to content

Commit 183cc58

Browse files
Merge pull request #12415 from Isira-Seneviratne/Zip-migrate-Path
Migrate zip import/export to use Path
2 parents 52ff052 + 4ffadc2 commit 183cc58

File tree

6 files changed

+75
-107
lines changed

6 files changed

+75
-107
lines changed

app/src/main/java/org/schabi/newpipe/settings/BackupRestoreSettingsFragment.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import androidx.activity.result.contract.ActivityResultContracts;
1818
import androidx.annotation.NonNull;
1919
import androidx.annotation.Nullable;
20-
import androidx.core.content.ContextCompat;
2120
import androidx.preference.Preference;
2221
import androidx.preference.PreferenceManager;
2322

@@ -35,12 +34,10 @@
3534
import org.schabi.newpipe.util.NavigationHelper;
3635
import org.schabi.newpipe.util.ZipHelper;
3736

38-
import java.io.File;
3937
import java.io.IOException;
4038
import java.text.SimpleDateFormat;
4139
import java.util.Date;
4240
import java.util.Locale;
43-
import java.util.Objects;
4441

4542
public class BackupRestoreSettingsFragment extends BasePreferenceFragment {
4643

@@ -61,13 +58,12 @@ public class BackupRestoreSettingsFragment extends BasePreferenceFragment {
6158
@Override
6259
public void onCreatePreferences(@Nullable final Bundle savedInstanceState,
6360
@Nullable final String rootKey) {
64-
final File homeDir = ContextCompat.getDataDir(requireContext());
65-
Objects.requireNonNull(homeDir);
66-
manager = new ImportExportManager(new BackupFileLocator(homeDir));
61+
final var dbDir = requireContext().getDatabasePath(BackupFileLocator.FILE_NAME_DB).toPath()
62+
.getParent();
63+
manager = new ImportExportManager(new BackupFileLocator(dbDir));
6764

6865
importExportDataPathKey = getString(R.string.import_export_data_path);
6966

70-
7167
addPreferencesFromResourceRegistry();
7268

7369
final Preference importDataPreference = requirePreference(R.string.import_data);
@@ -183,9 +179,7 @@ private void importDatabase(final StoredFileHelper file, final Uri importDataUri
183179
}
184180

185181
try {
186-
if (!manager.ensureDbDirectoryExists()) {
187-
throw new IOException("Could not create databases dir");
188-
}
182+
manager.ensureDbDirectoryExists();
189183

190184
// replace the current database
191185
if (!manager.extractDb(file)) {
Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package org.schabi.newpipe.settings.export
22

3-
import java.io.File
3+
import java.nio.file.Path
4+
import kotlin.io.path.div
45

56
/**
67
* Locates specific files of NewPipe based on the home directory of the app.
78
*/
8-
class BackupFileLocator(private val homeDir: File) {
9+
class BackupFileLocator(homeDir: Path) {
910
companion object {
1011
const val FILE_NAME_DB = "newpipe.db"
1112
@Deprecated(
@@ -16,13 +17,9 @@ class BackupFileLocator(private val homeDir: File) {
1617
const val FILE_NAME_JSON_PREFS = "preferences.json"
1718
}
1819

19-
val dbDir by lazy { File(homeDir, "/databases") }
20-
21-
val db by lazy { File(dbDir, FILE_NAME_DB) }
22-
23-
val dbJournal by lazy { File(dbDir, "$FILE_NAME_DB-journal") }
24-
25-
val dbShm by lazy { File(dbDir, "$FILE_NAME_DB-shm") }
26-
27-
val dbWal by lazy { File(dbDir, "$FILE_NAME_DB-wal") }
20+
val dbDir = homeDir / "databases"
21+
val db = homeDir / FILE_NAME_DB
22+
val dbJournal = homeDir / "$FILE_NAME_DB-journal"
23+
val dbShm = dbDir / "$FILE_NAME_DB-shm"
24+
val dbWal = dbDir / "$FILE_NAME_DB-wal"
2825
}

app/src/main/java/org/schabi/newpipe/settings/export/ImportExportManager.kt

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import java.io.FileNotFoundException
1212
import java.io.IOException
1313
import java.io.ObjectOutputStream
1414
import java.util.zip.ZipOutputStream
15+
import kotlin.io.path.createDirectories
16+
import kotlin.io.path.deleteIfExists
1517

1618
class ImportExportManager(private val fileLocator: BackupFileLocator) {
1719
companion object {
@@ -28,11 +30,8 @@ class ImportExportManager(private val fileLocator: BackupFileLocator) {
2830
// previous file size, the file will retain part of the previous content and be corrupted
2931
ZipOutputStream(SharpOutputStream(file.openAndTruncateStream()).buffered()).use { outZip ->
3032
// add the database
31-
ZipHelper.addFileToZip(
32-
outZip,
33-
BackupFileLocator.FILE_NAME_DB,
34-
fileLocator.db.path,
35-
)
33+
val name = BackupFileLocator.FILE_NAME_DB
34+
ZipHelper.addFileToZip(outZip, name, fileLocator.db)
3635

3736
// add the legacy vulnerable serialized preferences (will be removed in the future)
3837
ZipHelper.addFileToZip(
@@ -61,11 +60,10 @@ class ImportExportManager(private val fileLocator: BackupFileLocator) {
6160

6261
/**
6362
* Tries to create database directory if it does not exist.
64-
*
65-
* @return Whether the directory exists afterwards.
6663
*/
67-
fun ensureDbDirectoryExists(): Boolean {
68-
return fileLocator.dbDir.exists() || fileLocator.dbDir.mkdir()
64+
@Throws(IOException::class)
65+
fun ensureDbDirectoryExists() {
66+
fileLocator.dbDir.createDirectories()
6967
}
7068

7169
/**
@@ -75,16 +73,13 @@ class ImportExportManager(private val fileLocator: BackupFileLocator) {
7573
* @return true if the database was successfully extracted, false otherwise
7674
*/
7775
fun extractDb(file: StoredFileHelper): Boolean {
78-
val success = ZipHelper.extractFileFromZip(
79-
file,
80-
BackupFileLocator.FILE_NAME_DB,
81-
fileLocator.db.path,
82-
)
76+
val name = BackupFileLocator.FILE_NAME_DB
77+
val success = ZipHelper.extractFileFromZip(file, name, fileLocator.db)
8378

8479
if (success) {
85-
fileLocator.dbJournal.delete()
86-
fileLocator.dbWal.delete()
87-
fileLocator.dbShm.delete()
80+
fileLocator.dbJournal.deleteIfExists()
81+
fileLocator.dbWal.deleteIfExists()
82+
fileLocator.dbShm.deleteIfExists()
8883
}
8984

9085
return success

app/src/main/java/org/schabi/newpipe/util/ZipHelper.java

Lines changed: 21 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
import java.io.BufferedInputStream;
77
import java.io.ByteArrayInputStream;
88
import java.io.ByteArrayOutputStream;
9-
import java.io.File;
10-
import java.io.FileInputStream;
11-
import java.io.FileOutputStream;
129
import java.io.IOException;
1310
import java.io.InputStream;
1411
import java.io.OutputStream;
12+
import java.nio.file.Files;
13+
import java.nio.file.Path;
14+
import java.nio.file.StandardCopyOption;
1515
import java.util.zip.ZipEntry;
1616
import java.util.zip.ZipInputStream;
1717
import java.util.zip.ZipOutputStream;
@@ -37,9 +37,6 @@
3737
*/
3838

3939
public final class ZipHelper {
40-
41-
private static final int BUFFER_SIZE = 2048;
42-
4340
@FunctionalInterface
4441
public interface InputStreamConsumer {
4542
void acceptStream(InputStream inputStream) throws IOException;
@@ -55,17 +52,17 @@ private ZipHelper() { }
5552

5653

5754
/**
58-
* This function helps to create zip files. Caution this will overwrite the original file.
55+
* This function helps to create zip files. Caution, this will overwrite the original file.
5956
*
6057
* @param outZip the ZipOutputStream where the data should be stored in
6158
* @param nameInZip the path of the file inside the zip
62-
* @param fileOnDisk the path of the file on the disk that should be added to zip
59+
* @param path the path of the file on the disk that should be added to zip
6360
*/
6461
public static void addFileToZip(final ZipOutputStream outZip,
6562
final String nameInZip,
66-
final String fileOnDisk) throws IOException {
67-
try (FileInputStream fi = new FileInputStream(fileOnDisk)) {
68-
addFileToZip(outZip, nameInZip, fi);
63+
final Path path) throws IOException {
64+
try (var inputStream = Files.newInputStream(path)) {
65+
addFileToZip(outZip, nameInZip, inputStream);
6966
}
7067
}
7168

@@ -80,13 +77,13 @@ public static void addFileToZip(final ZipOutputStream outZip,
8077
final String nameInZip,
8178
final OutputStreamConsumer streamConsumer) throws IOException {
8279
final byte[] bytes;
83-
try (ByteArrayOutputStream byteOutput = new ByteArrayOutputStream()) {
80+
try (var byteOutput = new ByteArrayOutputStream()) {
8481
streamConsumer.acceptStream(byteOutput);
8582
bytes = byteOutput.toByteArray();
8683
}
8784

88-
try (ByteArrayInputStream byteInput = new ByteArrayInputStream(bytes)) {
89-
ZipHelper.addFileToZip(outZip, nameInZip, byteInput);
85+
try (var byteInput = new ByteArrayInputStream(bytes)) {
86+
addFileToZip(outZip, nameInZip, byteInput);
9087
}
9188
}
9289

@@ -97,49 +94,26 @@ public static void addFileToZip(final ZipOutputStream outZip,
9794
* @param nameInZip the path of the file inside the zip
9895
* @param inputStream the content to put inside the file
9996
*/
100-
public static void addFileToZip(final ZipOutputStream outZip,
101-
final String nameInZip,
102-
final InputStream inputStream) throws IOException {
103-
final byte[] data = new byte[BUFFER_SIZE];
104-
try (BufferedInputStream bufferedInputStream =
105-
new BufferedInputStream(inputStream, BUFFER_SIZE)) {
106-
final ZipEntry entry = new ZipEntry(nameInZip);
107-
outZip.putNextEntry(entry);
108-
int count;
109-
while ((count = bufferedInputStream.read(data, 0, BUFFER_SIZE)) != -1) {
110-
outZip.write(data, 0, count);
111-
}
112-
}
97+
private static void addFileToZip(final ZipOutputStream outZip,
98+
final String nameInZip,
99+
final InputStream inputStream) throws IOException {
100+
outZip.putNextEntry(new ZipEntry(nameInZip));
101+
inputStream.transferTo(outZip);
113102
}
114103

115104
/**
116-
* This will extract data from ZipInputStream. Caution this will overwrite the original file.
105+
* This will extract data from ZipInputStream. Caution, this will overwrite the original file.
117106
*
118107
* @param zipFile the zip file to extract from
119108
* @param nameInZip the path of the file inside the zip
120-
* @param fileOnDisk the path of the file on the disk where the data should be extracted to
109+
* @param path the path of the file on the disk where the data should be extracted to
121110
* @return will return true if the file was found within the zip file
122111
*/
123112
public static boolean extractFileFromZip(final StoredFileHelper zipFile,
124113
final String nameInZip,
125-
final String fileOnDisk) throws IOException {
126-
return extractFileFromZip(zipFile, nameInZip, input -> {
127-
// delete old file first
128-
final File oldFile = new File(fileOnDisk);
129-
if (oldFile.exists()) {
130-
if (!oldFile.delete()) {
131-
throw new IOException("Could not delete " + fileOnDisk);
132-
}
133-
}
134-
135-
final byte[] data = new byte[BUFFER_SIZE];
136-
try (FileOutputStream outFile = new FileOutputStream(fileOnDisk)) {
137-
int count;
138-
while ((count = input.read(data)) != -1) {
139-
outFile.write(data, 0, count);
140-
}
141-
}
142-
});
114+
final Path path) throws IOException {
115+
return extractFileFromZip(zipFile, nameInZip, input ->
116+
Files.copy(input, path, StandardCopyOption.REPLACE_EXISTING));
143117
}
144118

145119
/**

app/src/test/java/org/schabi/newpipe/settings/ImportAllCombinationsTest.kt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ import org.schabi.newpipe.streams.io.StoredFileHelper
1010
import us.shandian.giga.io.FileStream
1111
import java.io.File
1212
import java.io.IOException
13-
import java.nio.file.Files
13+
import kotlin.io.path.createTempFile
14+
import kotlin.io.path.exists
15+
import kotlin.io.path.fileSize
1416

1517
class ImportAllCombinationsTest {
1618

@@ -47,10 +49,10 @@ class ImportAllCombinationsTest {
4749
BackupFileLocator::class.java,
4850
Mockito.withSettings().stubOnly()
4951
)
50-
val db = File.createTempFile("newpipe_", "")
51-
val dbJournal = File.createTempFile("newpipe_", "")
52-
val dbWal = File.createTempFile("newpipe_", "")
53-
val dbShm = File.createTempFile("newpipe_", "")
52+
val db = createTempFile("newpipe_", "")
53+
val dbJournal = createTempFile("newpipe_", "")
54+
val dbWal = createTempFile("newpipe_", "")
55+
val dbShm = createTempFile("newpipe_", "")
5456
Mockito.`when`(fileLocator.db).thenReturn(db)
5557
Mockito.`when`(fileLocator.dbJournal).thenReturn(dbJournal)
5658
Mockito.`when`(fileLocator.dbShm).thenReturn(dbShm)
@@ -62,15 +64,15 @@ class ImportAllCombinationsTest {
6264
Assert.assertFalse(dbJournal.exists())
6365
Assert.assertFalse(dbWal.exists())
6466
Assert.assertFalse(dbShm.exists())
65-
Assert.assertTrue("database file size is zero", Files.size(db.toPath()) > 0)
67+
Assert.assertTrue("database file size is zero", db.fileSize() > 0)
6668
}
6769
} else {
6870
runTest {
6971
Assert.assertFalse(ImportExportManager(fileLocator).extractDb(zip))
7072
Assert.assertTrue(dbJournal.exists())
7173
Assert.assertTrue(dbWal.exists())
7274
Assert.assertTrue(dbShm.exists())
73-
Assert.assertEquals(0, Files.size(db.toPath()))
75+
Assert.assertEquals(0, db.fileSize())
7476
}
7577
}
7678

0 commit comments

Comments
 (0)