Java打包生成iso9660以及解包iso9660实现记录

2022-12-01  本文已影响0人  haiyong6

iso9660

ISO 9660文件系统是一个标准的CD-ROM文件系统,它允许您在PC、Mac和其它主要计算机平台上读取CD-ROM文件。
------摘自百度百科

使用genisoimage linux命令的方式打包iso9660

String shellCommand = "genisoimage -input-charset utf-8 -o " + isoTempPath + " -iso-level 1 -r -l " + targetFileDir;

其中的isoTempPath 是生成iso的存储路径,targetFileDir是默认把这个文件夹下所有的文件都打进iso包里。

这种方式依赖服务器安装的genisoimage命令,如果做服务迁移得确保服务器中安装了这个命令。

纯java实现iso9660

在github上找到一个国外大佬的实现方式:https://github.com/stephenc/java-iso-tools.git
可以把源码下载下来,在examples文件夹里有使用方法介绍。

或者看我下面总结的:
maven引入:

        <dependency>
            <groupId>com.github.stephenc.java-iso-tools</groupId>
            <artifactId>iso9660-writer</artifactId>
            <version>2.1.0</version>
        </dependency>
        <dependency>
            <groupId>com.github.stephenc.java-iso-tools</groupId>
            <artifactId>loop-fs-iso-impl</artifactId>
            <version>2.0.1</version>
        </dependency>

打包

新建IsoCreation工具类:

package org.openjfx.offlinepackage.utils;

import java.io.File;
import java.io.FileNotFoundException;

import com.github.stephenc.javaisotools.eltorito.impl.ElToritoConfig;
import com.github.stephenc.javaisotools.iso9660.ConfigException;
import com.github.stephenc.javaisotools.iso9660.ISO9660RootDirectory;
import com.github.stephenc.javaisotools.iso9660.impl.CreateISO;
import com.github.stephenc.javaisotools.iso9660.impl.ISO9660Config;
import com.github.stephenc.javaisotools.iso9660.impl.ISOImageFileHandler;
import com.github.stephenc.javaisotools.joliet.impl.JolietConfig;
import com.github.stephenc.javaisotools.rockridge.impl.RockRidgeConfig;
import com.github.stephenc.javaisotools.sabre.HandlerException;

public class IsoCreation {
    ISO9660RootDirectory root;
    ISO9660Config iso9660config;
    RockRidgeConfig rockConfig;
    JolietConfig jolietConfig;
    ElToritoConfig elToritoConfig;

    // This is a conversion of https://github.com/danveloper/provisioning-gradle-plugin/blob/
    // master/src/main/groovy/gradle/plugins/provisioning/tasks/image/ImageAssemblyTask.groovy
    public IsoCreation() {
        root = new ISO9660RootDirectory();
    }

    public void insertFile(File passedInsert) {
        try {
            root.addContentsRecursively(passedInsert);
        } catch (HandlerException e) {
            e.printStackTrace();
        }
    }

    public ISO9660Config setIsoConfig(String volumeId) {
        //Let's make a new configuration for the basic file system
        iso9660config = new ISO9660Config();
        iso9660config.allowASCII(false);
        //The standard says you are not allowed more than 8 levels, unless you enable RockRidge support
        iso9660config.restrictDirDepthTo8(true);
        //Set the volume ID
        try {
            iso9660config.setVolumeID(volumeId.substring(0, Math.min(volumeId.length(), 15)));
        } catch (ConfigException e) {
            e.printStackTrace();
        }
        iso9660config.forceDotDelimiter(false);
        try {
            iso9660config.setInterchangeLevel(3);
        } catch (ConfigException e) {
            e.printStackTrace();
        }

        return iso9660config;
    }

    public RockRidgeConfig setRockConfig() {
        rockConfig = new RockRidgeConfig();
        rockConfig.setMkisofsCompatibility(false);
        rockConfig.hideMovedDirectoriesStore(true);
        rockConfig.forcePortableFilenameCharacterSet(true);
        return rockConfig;
    }

    public JolietConfig setJolietConfig(String volumeId) {
        jolietConfig = new JolietConfig();
        try {
            //Not sure if there is a limit here, but it seems most names are fine
            jolietConfig.setVolumeID(volumeId);
        } catch (ConfigException e) {
            e.printStackTrace();
        }
        jolietConfig.forceDotDelimiter(false);
        return jolietConfig;
    }

    /**
     * This is for boot information on the iso
     *
     * @return The finalized config.
     */
    public ElToritoConfig setElToritoConfig(){
        elToritoConfig = null;
        return elToritoConfig;
    }

    /**
     * Close out the disc.
     * @param isoPath
     */
    public void finalizeDisc(File isoPath) {
        ISOImageFileHandler handler = null;
        try {
            handler = new ISOImageFileHandler(isoPath);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        try {
            CreateISO iso = new CreateISO(handler, root);
            try {
                iso.process(iso9660config, rockConfig, jolietConfig, elToritoConfig);

            } catch (HandlerException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

封装createIso方法

public static void createIso(String inputFileDir, String outIsoPath) {
        //Create a new root of our disc
        IsoCreation sampleCreation = new IsoCreation();
        //Add our files, you have to give a directory to use the recusively adding function
        sampleCreation.insertFile(new File(inputFileDir));
        //This is the base iso9660 standard file system
        sampleCreation.setIsoConfig("test");
        //To quote wikipedia "Rock Ridge is an extension to the ISO 9660 volume format, commonly used on CD-ROM and
        // DVD media, which adds POSIX file system semantics."
//        sampleCreation.setRockConfig();
        //This is another extension to the standard after Windows 95 to add support for longer filenames
        sampleCreation.setJolietConfig("test");
        //El Torito is boot information for the disc
//        sampleCreation.setElToritoConfig();
        //Finalize and save our ISO
        sampleCreation.finalizeDisc(new File(outIsoPath));
    }

然后调用这个方法

createIso(targetFileDir, isoTempPath);

其中targetFileDir是要打包的文件夹 isoTempPath是打包之后iso存储的路径,如此就可以打包成功。

解压包

新建ReadIso工具类:

package org.openjfx.offlinepackage.utils;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;

import com.github.stephenc.javaisotools.loopfs.iso9660.Iso9660FileEntry;
import com.github.stephenc.javaisotools.loopfs.iso9660.Iso9660FileSystem;

/***
 * This is a adaptation of https://github.com/danveloper/provisioning-gradle-plugin/blob/master/src/main/groovy/
 * gradle/plugins/provisioning/tasks/image/ImageAssemblyTask.groovy
 */

public class ReadIso {
    Iso9660FileSystem discFs;

    public ReadIso(File isoToRead, File saveLocation) {

        try {
            //Give the file and mention if this is treated as a read only file.
            discFs = new Iso9660FileSystem(isoToRead, true);
        } catch (IOException e) {
            e.printStackTrace();
        }

        //Make our saving folder if it does not exist
        if (!saveLocation.exists()) {
            saveLocation.mkdirs();
        }

        //Go through each file on the disc and save it.
        for (Iso9660FileEntry singleFile : discFs) {
            if (singleFile.isDirectory()) {
                new File(saveLocation, singleFile.getPath()).mkdirs();
            } else {
                File tempFile = new File(saveLocation, singleFile.getPath());
                try {
                    //This is java 7, sorry if that is too new for some people
                    Files.copy(discFs.getInputStream(singleFile), tempFile.toPath());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

调用下面方法解压包:

 ReadIso tempIso = new ReadIso(new File("test.iso"), new File("test directory"));

其中第一个参数是iso的File对象,第二个参数是解压路径的File对象。

至此java实现iso9660打包和解包都可实现,完结撒花~

上一篇下一篇

猜你喜欢

热点阅读