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());
但它没有帮助。请有人给我最后的解决方案。
答案 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");