DraqueT / PolyGlot

PolyGlot is a conlang construction toolkit.
MIT License
381 stars 44 forks source link

Corrupted File Recovery System #1283

Closed DraqueT closed 1 year ago

DraqueT commented 1 year ago

Implement a system for recovering from corrupted files. The xml file is saved first in the zip archive, so it is the most likely to be recoverable, especially in larger archives. In addition to this, the XML recovery tool must also be updated. Currently, if the XML file has garbage text at its end, or too many missing closing tags, it will simply fail to load. Attached is a corrupted archive which is good to test this feature with (zip added to end of file simply due to Github requirements).

This library is compatible with the Java Module system and should allow for recovery:

  <dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-compress</artifactId>
    <version>1.21</version>
  </dependency>

. . .

    requires org.apache.commons.compress;

Here is the basic code example of how to implement this:

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class ZipRecovery {

    public static void recoverDataFromCorruptedZip(String corruptedZipPath, String outputFolderPath) {
        try (ZipFile zipFile = new ZipFile(new File(corruptedZipPath))) {
            File outputFolder = new File(outputFolderPath);

            if (!outputFolder.exists()) {
                outputFolder.mkdirs();
            }

            zipFile.getEntries().forEachRemaining(entry -> {
                try (InputStream inputStream = zipFile.getInputStream(entry)) {
                    File outputFile = new File(outputFolder, entry.getName());
                    try (OutputStream outputStream = new FileOutputStream(outputFile)) {
                        byte[] buffer = new byte[1024];
                        int bytesRead;
                        while ((bytesRead = inputStream.read(buffer)) != -1) {
                            outputStream.write(buffer, 0, bytesRead);
                        }
                    }
                } catch (IOException e) {
                    System.err.println("Error while extracting entry: " + entry.getName());
                }
            });
        } catch (IOException e) {
            System.err.println("Error while reading the zip file: " + e.getMessage());
        }
    }

}

recover.archive.pgd.zip