[JAVA] [Kotlin] Japanische Dateien mit ZIP-Komprimierung

Einführung

Wird während der ZIP-Komprimierung verwendet, dh mit ZipOutputStream Der Standardwert für den Zeichensatz ist UTF-8.

Der japanische Dateiname für Windows lautet MS932. Wenn er also unverändert bleibt, wird er beim Dekomprimieren mit Windows verstümmelt. Geben Sie daher in ZipOutputStream einen Zeichensatz an, um verstümmelte Zeichen zu vermeiden. Es gibt viele ähnliche Artikel in Java, aber nur wenige in Kotlin, also werde ich sie fallen lassen.

Ich bin mit Kotlin (Java) nicht so vertraut, dass ich nicht weiß, wie man FileInputStream verwendet. Ich würde es begrüßen, wenn Sie mir eine bessere Art des Schreibens beibringen könnten.

Was Sie in diesem Artikel sehen können

ZIP-Komprimierung (japanische Unterstützung) mit Kotlin.

Artikel, die ich als Referenz verwendet habe

Code

import java.io.BufferedOutputStream
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.nio.charset.Charset
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream

/**
 *ZIP archiviert die Dateien in der angegebenen ArrayList und erstellt sie im angegebenen Pfad.
 *Der Standardzeichencode ist Shift_Da es sich um JIS handelt, können auch japanische Dateinamen unterstützt werden.
 *
 * @param fromFiles Liste der zu komprimierenden Dateien.(Beispiel; {C:/sample1.txt, C:/sample2.txt} )
 * @param toZipFile Geben Sie den komprimierten Dateinamen mit dem vollständigen Pfad an.(Beispiel: C:/sample.zip )
 * @param charset Zeichensatz, der bei der Konvertierung in Zip verwendet wird. * 1
 */
fun zipFiles(fromFiles: List<File>, toZipFile: File, charset: Charset = Charset.forName("MS932")) {
    try {
        //Wenn Sie use verwenden, wird die Ressource automatisch geschlossen, wenn der Bereich endet.
        //Geben Sie im ersten Argument von ZipOutputStream die zu komprimierende Datei an.
        //Wenn das zweite Argument von ZipOutputStream leer ist, ist Charset UTF-Es wird 8 sein.
        ZipOutputStream(BufferedOutputStream(FileOutputStream(toZipFile)), charset).use { zipOutputStream ->
            fromFiles.forEach { file ->
                if (file.isFile) {
                    archiveFile(zipOutputStream, file, file.name)
                } else if (file.isDirectory) {
                    archiveDirectory(zipOutputStream, file, file)
                }
            }
        }
    } catch (e: Exception) {
        //Fehlerbehandlung.
    }
}

/**
 *ZIP archiviert die Dateien in der angegebenen ArrayList und erstellt sie im angegebenen Pfad.
 *Der Standardzeichencode ist Shift_Da es sich um JIS handelt, können auch japanische Dateinamen unterstützt werden.
 *
 * @param zipOutputStream Stream zum Schreiben der Zieldatei.
 * @param baseFile Die Stammdatei des zu komprimierenden Verzeichnisses.
 * @param targetFile Das zu komprimierende Verzeichnis.
 */
fun archiveDirectory(zipOutputStream: ZipOutputStream, baseFile: File, targetFile: File) {
    targetFile.listFiles()?.forEach { file ->
        if (file.isDirectory) {
            archiveDirectory(zipOutputStream, baseFile, file)
        } else if (file.isFile) {
            //Da entryName als relativer Pfad angegeben werden muss, rufen Sie den relativen Pfad zu baseFile ab.
            val relativeEntryName = file.toRelativeString(baseFile.parentFile)
            archiveFile(zipOutputStream, file, relativeEntryName)
        } else {
            //Wenn die Datei nicht vorhanden ist, ist sie weder isDirectory noch isFile.
            //Wenn Sie in diesem Fall verarbeiten möchten, schreiben Sie den Prozess hier.
        }
    }
}

/**
 *ZIP archiviert die Dateien in der angegebenen ArrayList und erstellt sie im angegebenen Pfad.
 *Der Standardzeichencode ist Shift_Da es sich um JIS handelt, können auch japanische Dateinamen unterstützt werden.
 *
 * @param zipOutputStream Stream zum Schreiben der Zieldatei.
 * @param targetFile Zu komprimierende Datei.
 * @param entryName Dateiname beim Schreiben von targetFile in zipOutputStream(Relativer Pfad)。
 *          ex) hoge/fuga.Wenn es txt ist, sprudeln Sie.zip/hoge/fuga.Eine Datei wird in txt erstellt.
 */
fun archiveFile(zipOutputStream: ZipOutputStream, targetFile: File, entryName: String) {
    // ※2
    val zipBufferSize = 100 * 1024
    // ${Von ZipOutputStream angegebener Dateipfad} / ${entryName}Die Datei wird in erstellt.
    zipOutputStream.putNextEntry(ZipEntry(entryName))
    FileInputStream(targetFile).use { inputStream ->
        val bytes = ByteArray(zipBufferSize)
        var length: Int
        //Lesen Sie die Datei für zipBufferSize. Nach dem Laden-Rückgabe 1.
        while (inputStream.read(bytes).also { length = it } != -1) {
            zipOutputStream.write(bytes, 0, length)
        }
    }
    //Der Eintrag wird bei Verwendung nicht geschlossen und muss manuell geschlossen werden.
    zipOutputStream.closeEntry()
}

Note

* 1 Informationen zum zu verwendenden Zeichensatz

Dieses Mal wird MS932 als zu verwendender Zeichensatz ausgewählt. Der Grund für die Verwendung von MS932 anstelle von SHIFT_JIS, einem ähnlichen Zeichencode, basiert auf dem folgenden Artikel.

* 2 Informationen zur von FileInputStream verwendeten Puffergröße

Referenz: Java-Dateikopie (Puffergröße ändern) バッファサイズ

Dieses Mal betrug die geschätzte Größe der hochgeladenen Datei etwa 1 MB bis 5 MB, daher habe ich 100 KB angegeben.

Über net.lingala.zip4j.ZipFile

Net.lingala.zip4j.ZipFile mit vielen nützlichen Funktionen ist Charset Es kann nicht geändert werden. Wenn Sie Japanisch unterstützen möchten, verwenden Sie daher java.util.zip.

Recommended Posts

[Kotlin] Japanische Dateien mit ZIP-Komprimierung
[Kotlin] Doppelte Dateien löschen [Java]