Modified zip implementation to preserve filenames of single file resources.

Also modified the directory structure of single file resources to make them consistent with multi file resources.

For multi file resources, the original folder is renamed to "data", resulting in a layout such as:
data/file1.txt
data/file2.txt
data/dir1/file3.txt

For single file resources, the file is now moved into a "data" folder, like so:
data/file.txt

This is slightly unconventional, but is appropriate within the context of QDN to keep everything consistent.
This commit is contained in:
CalDescent
2021-12-06 19:53:20 +00:00
parent 19240a9caf
commit 2efac0c96b
5 changed files with 92 additions and 40 deletions

View File

@@ -420,19 +420,6 @@ public class ArbitraryDataReader {
throw new DataException(String.format("Unable to unzip file: %s", e.getMessage()));
}
// If unzipped data was a file not a directory, move it into a data/ directory so that the .qortal
// metadata folder is able to be created there too
if (this.uncompressedPath.toFile().isFile()) {
// Rename to temporary filename
Path tempDest = Paths.get(this.uncompressedPath.getParent().toString(), "data2");
this.uncompressedPath.toFile().renameTo(tempDest.toFile());
// Create a "data" directory
Files.createDirectories(this.uncompressedPath);
// Move the original file into the newly created directory
Path finalPath = Paths.get(this.uncompressedPath.toString(), "data");
tempDest.toFile().renameTo(finalPath.toFile());
}
// Replace filePath pointer with the uncompressed file path
if (FilesystemUtils.pathInsideDataOrTempPath(this.filePath)) {
if (Files.exists(this.filePath)) {

View File

@@ -184,8 +184,8 @@ public class ArbitraryDataWriter {
if (this.compression == Compression.ZIP) {
LOGGER.info("Compressing...");
String fileName = "data"; //isSingleFile ? singleFileName : null;
ZipUtils.zip(this.filePath.toString(), this.compressedPath.toString(), fileName);
String enclosingFolderName = "data";
ZipUtils.zip(this.filePath.toString(), this.compressedPath.toString(), enclosingFolderName);
}
else {
throw new DataException(String.format("Unknown compression type specified: %s", compression.toString()));

View File

@@ -21,6 +21,8 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Code modified in 2021 for Qortal Core
*
*/
package org.qortal.utils;
@@ -31,44 +33,54 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
public class ZipUtils {
public static void zip(String sourcePath, String destFilePath, String fileName) throws IOException, InterruptedException {
public static void zip(String sourcePath, String destFilePath, String enclosingFolderName) throws IOException, InterruptedException {
File sourceFile = new File(sourcePath);
if (fileName == null) {
fileName = sourceFile.getName();
}
boolean isSingleFile = Paths.get(sourcePath).toFile().isFile();
FileOutputStream fileOutputStream = new FileOutputStream(destFilePath);
ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream);
ZipUtils.zip(sourceFile, fileName, zipOutputStream);
ZipUtils.zip(sourceFile, enclosingFolderName, zipOutputStream, isSingleFile);
zipOutputStream.close();
fileOutputStream.close();
}
public static void zip(final File fileToZip, final String fileName, final ZipOutputStream zipOut) throws IOException, InterruptedException {
public static void zip(final File fileToZip, final String enclosingFolderName, final ZipOutputStream zipOut, boolean isSingleFile) throws IOException, InterruptedException {
if (Controller.isStopping()) {
throw new InterruptedException("Controller is stopping");
}
// Handle single file resources slightly differently
if (isSingleFile) {
// Create enclosing folder
zipOut.putNextEntry(new ZipEntry(enclosingFolderName + "/"));
zipOut.closeEntry();
// Place the supplied file within the folder
ZipUtils.zip(fileToZip, enclosingFolderName + "/" + fileToZip.getName(), zipOut, false);
return;
}
if (fileToZip.isDirectory()) {
if (fileName.endsWith("/")) {
zipOut.putNextEntry(new ZipEntry(fileName));
if (enclosingFolderName.endsWith("/")) {
zipOut.putNextEntry(new ZipEntry(enclosingFolderName));
zipOut.closeEntry();
} else {
zipOut.putNextEntry(new ZipEntry(fileName + "/"));
zipOut.putNextEntry(new ZipEntry(enclosingFolderName + "/"));
zipOut.closeEntry();
}
final File[] children = fileToZip.listFiles();
for (final File childFile : children) {
ZipUtils.zip(childFile, fileName + "/" + childFile.getName(), zipOut);
ZipUtils.zip(childFile, enclosingFolderName + "/" + childFile.getName(), zipOut, false);
}
return;
}
final FileInputStream fis = new FileInputStream(fileToZip);
final ZipEntry zipEntry = new ZipEntry(fileName);
final ZipEntry zipEntry = new ZipEntry(enclosingFolderName);
zipOut.putNextEntry(zipEntry);
final byte[] bytes = new byte[1024];
int length;