使用DiscUtils从目录创建iso文件

时间:2013-07-19 06:53:03

标签: c# exception iso

Iam尝试使用discutils从目录构建一个iso文件。这段代码适用于几个文件,但过了一段时间后,我抛出一个异常,说明“isoBuilder.AddFile(fileOnIso,br.BaseStream);”中的“具有相同密钥的对象已经存在”。我不明白为什么会发生这样的事情,有人可以解释一下吗?

public void AddtoISO(string directory,string isoFile)
    {
        BinaryReader br;
        long bytesRemain = 0;
        long totalBytesWritten = 0;
        DirectoryInfo rootDirToAdd = new DirectoryInfo(sourceName);
        DirectoryInfo currentDirToAdd = new DirectoryInfo(directory);

        try
        {
            foreach (FileInfo file in currentDirToAdd.GetFiles())
            {

                string fileFullPath = file.FullName;
                string fileOnIso = fileFullPath.Substring(fileFullPath.IndexOf(rootDirToAdd.Name) + rootDirToAdd.Name.Length + 1);

                Console.WriteLine(fileOnIso);

                br = new BinaryReader(file.OpenRead());

                while(totalBytesWritten < file.Length)
                {                       
                    bytesRemain = file.Length - totalBytesWritten;

                    br.ReadBytes(blockSize);
                    isoBuilder.AddFile(fileOnIso,br.BaseStream);

                    if(bytesRemain<blockSize)
                    {
                        totalBytesWritten += bytesRemain;
                        totalBytesAdded += bytesRemain;
                    }
                    else
                    {
                        totalBytesWritten += blockSize;
                        totalBytesAdded += blockSize;
                    }

                }

                itemsAdded++;
                totalBytesWritten = 0;

            }
            foreach (DirectoryInfo subdir in currentDirToAdd.GetDirectories())
            {
                string folderFullPath = subdir.FullName;
                string folderOnIso = folderFullPath.Substring(folderFullPath.IndexOf(rootDirToAdd.Name) + rootDirToAdd.Name.Length + 1);

                isoBuilder.AddDirectory(folderOnIso);
                itemsAdded++;

                AddtoISO(subdir.FullName,isoFile,ctoken);
            }

            isoBuilder.Build(isoFile);

        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            Console.WriteLine(ex.StackTrace);
        }

    }

更新 避免流的另一种可能的实现方式,缺点是在3GB iso上需要花费太多时间(超过30分钟),例如,当使用ultraiso构建时,需要大约4分钟......任何想法?

public void AddtoISO(string directory,string isoFile)
    {

        try
        {
            DirectoryInfo rootDirToAdd = new DirectoryInfo(sourceName);
            DirectoryInfo currentDirToAdd = new DirectoryInfo(directory);

            foreach (FileInfo file in currentDirToAdd.GetFiles())
            {
                string fileOnHdd = file.FullName;
                string fileOnIso = fileOnHdd.Substring(fileOnHdd.IndexOf(rootDirToAdd.Name) + rootDirToAdd.Name.Length + 1);
                Console.WriteLine(fileOnIso);
                isoBuilder.AddFile(fileOnIso,fileOnHdd);
                itemsAdded++;
            }
            foreach (DirectoryInfo subdir in currentDirToAdd.GetDirectories())
            {
                itemsAdded++;
                AddtoISO(subdir.FullName,isoFile,ctoken);
            }

            isoBuilder.Build(isoFile);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            Console.WriteLine(ex.StackTrace);
        }

    }

更新

如果目录结构如下,则抛出异常:

\引导\引导

它似乎为引导目录创建了密钥,当它遇到boot.ext文件时,它错误地认为它是双重添加。换句话说,当文件包含其包含目录的名称时。

测试建筑物dsl-4.11.rc1.iso

的index.html 靴 开机\ ISOLINUX 启动\ ISOLINUX \ boot.cat 启动\ ISOLINUX \ boot.msg 启动\ ISOLINUX \ F2 启动\ ISOLINUX \ F3 启动\ ISOLINUX \ german.kbd 启动\ ISOLINUX \ isolinux.bin 启动\ ISOLINUX \的isolinux.cfg 启动\ ISOLINUX \ linux24 启动\ ISOLINUX \ logo.16 启动\ ISOLINUX \ minirt24.gz KNOPPIX KNOPPIX \ KNOPPIX 关于KNOPPIX \ KNOPPIX的问题

更新2

最后取得了一些进展..错误不在任何给定的路径中,但我的假设是我必须继续调用isobuilder.Addfile()直到文件流完全添加到iso。

我不得不搬家:

isoBuilder.AddFile(fileOnIso,br.BaseStream);

在foreach关闭括号之前。这样就不必在iso中一次又一次地添加。

最后一个问题是在

 isoBuilder.Build(isoFile);

抱怨文件被关闭的地方。我试图纠正它:

FileInfo fi = new FileInfo(isoFile);
isoBuilder.Build(fi.OpenWrite());

但它没有帮助。请有人给我最后的解决方案。

1 个答案:

答案 0 :(得分:0)

我知道这很老了,但是我想如果以后有人需要帮助的话,可以发帖。

以下是我用来构建ISO using DiscUtils.Iso9660

的快速高效的功能
public string CreateIsoImage(string sourceDrive, string targetIso, string volumeName)
{
    try
    {
        var iso = new CDBuilder
        {
            UseJoliet = true,
            VolumeIdentifier = volumeName
        };

        foreach(string file in Directory.GetFiles(sourceDrive, "*", SearchOption.AllDirectories))
        {
            var fi = new FileInfo(file);
            if (fi.Directory.Name == sourceDrive)
            {
                iso.AddFile($"{fi.Name}", fi.FullName);
                continue;
            }
            var dirStruct = fi.Directory.FullName.Replace(sourceDrive, string.Empty).TrimEnd('\\');
            iso.AddDirectory(dirStruct);
            iso.AddFile($"{dirStruct}\\{fi.Name}", fi.FullName);
        }

        iso.Build(targetIso);
        return "Success";
    }
    catch (Exception ex)
    {
        return ex.Message;
    }
}

用法:

CreateIsoImage("D:\\", "C:\\Temp\\MyIsoImage.iso", "MyVolumeName");