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

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打包和解包都可实现,完结撒花~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,688评论 1 330
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,559评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,749评论 0 226
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,581评论 0 191
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,741评论 3 271
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,684评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,122评论 2 292
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,847评论 0 182
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,441评论 0 228
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,939评论 2 232
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,333评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,783评论 2 236
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,275评论 3 220
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,830评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,444评论 0 180
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,553评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,618评论 2 249

推荐阅读更多精彩内容

  • 常用的ADB命令 1. 显示系统中全部Android平台: android list targets 2. 显示系...
    voiletic阅读 2,167评论 0 1
  • 一、安装和登录命令 reboot 1.作用 reboot命令的作用是重新启动计算机,它的使用权限是系统管理者。 2...
    秃鹰人生阅读 2,157评论 0 1
  • 1.Linux下如何用命令查看实时日志(完整命令) tail -f 路径.log查看前多少行 tai-200f 路...
    qianyewhy阅读 2,174评论 0 11
  • 1、linux命令格式 我们刚登录之后,总会看到这个这个东西: 中括号[]没有特别的意思,root这块是指的用户名...
    大嘴蝸牛阅读 400评论 0 0
  • 1.shutdown:关机指令,建议先使用sync进行数据保存之后再关机2.reboot:电脑重启,服务器不建议重...
    墨宇暗黑阅读 746评论 0 9