zoukankan      html  css  js  c++  java
  • 文件数量较多的情况下如何提高刻录速度(调用IMAPI2实现DVD刻录功能)

    在调用IMAPI2实现DVD刻录功能时,如果文件数量较多时,刻录占用的时间也较长,因此考虑先将刻录文件制作成ISO files,然后再刻录到DVD中。以此来优化刻录功能。

    调用IMAPI2的方法在www.codeproject.com 有例子可以参考,网址为http://www.codeproject.com/KB/winsdk/IMAPI2.aspx 。在此就不再班门弄斧,下面讲讲Creating ISO files的方法。

    1.  创建镜像文件

    using System.Runtime.InteropServices;

    using System.Runtime.InteropServices.ComTypes;

    using IMAPI2.Interop;

    //Import this legacy Win32API...

    [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)] static internal extern uint SHCreateStreamOnFile (string pszFile, uint grfMode, out IStream ppstm);

    //Create

    IFileSystemImage ifsi = new MsftFileSystemImage();
    ifsi.ChooseImageDefaultsForMediaType(IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DISK);
    ifsi.FileSystemsToCreate =
        FsiFileSystems.FsiFileSystemJoliet | FsiFileSystems.FsiFileSystemISO9660;
    ifsi.VolumeName = "YourVolume";
    ifsi.Root.AddTree("c:\\YourDirToArchive", true);//use a valid folder
    //this will implement the Write method for the formatter
    IStream imagestream = ifsi.CreateResultImage().ImageStream;
    if (imagestream != null)
    {
        System.Runtime.InteropServices.ComTypes.STATSTG stat;
        imagestream.Stat(out stat, 0x01);
        IStream newStream;
        if (0 == SHCreateStreamOnFile
            ("C:\\YourImage.iso", 0x00001001, out newStream) && newStream != null)
        {
            IntPtr inBytes = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(long)));
            IntPtr outBytes = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(long)));
            try
            {
                imagestream.CopyTo(newStream, stat.cbSize, inBytes, outBytes);
                Marshal.ReleaseComObject(imagestream);
                imagestream = null;
                newStream.Commit(0);
            }
            finally
            {
                Marshal.ReleaseComObject(newStream);
                Marshal.FreeHGlobal(inBytes);
                Marshal.FreeHGlobal(outBytes);
                if (imagestream != null)
                    Marshal.ReleaseComObject(imagestream);
            }
        }
    }
    Marshal.ReleaseComObject(ifsi);

    2.  增加单独的文件到镜像中

    使用IFsiDirectoryItem记录文件的原始路径,使用Update事件跟踪进程。

    private void CreateFSIFile(FileInfo file, IFsiDirectoryItem diritem)
    {
        string realpath = UniqueListFileSystemInfo.GetPhysicalPath(file.FullName);
        int index = realpath.IndexOf(":\\") + 1;
        if (_sysImage.Exists(realpath.Substring(index)) == FsiItemType.FsiItemNotFound)
        {
            IFsiDirectoryItem crtdiritem = diritem as IFsiDirectoryItem;
            string name = Path.GetFileName(realpath);
            if (string.Compare(diritem.FullPath,
                Path.GetDirectoryName(realpath).Substring(index), true) != 0)
            {
                string fsipath = Path.GetDirectoryName(realpath).Substring
                (index + 1 + diritem.FullPath.Length);
                string[] dirs = fsipath.Split('\\');

                //create the subdirs one by one
                foreach (string dir in dirs)
                {
                    if (dir.Length == 0)
                        continue;//in the root like C:\
                    try
                    {
                        string newpath = string.Format("{0}\\{1}", crtdiritem.FullPath, dir);
                        if (_sysImage.Exists(newpath) != FsiItemType.FsiItemDirectory)
                            crtdiritem.AddDirectory(dir);
                    }
                    catch
                    {
                        Cancel = true;
                        throw;
                    }
                    crtdiritem = crtdiritem[dir] as IFsiDirectoryItem;
                }
            }

            System.Runtime.InteropServices.ComTypes.IStream newStream = null;

            try
            {
                newStream = LoadCOMStream(realpath);
                crtdiritem.AddFile(name, newStream);
            }
            finally
            {
                Marshal.ReleaseComObject(newStream);
            }

            _actualSize += ((FileInfo)file).Length;
            if (Update != null && Update.GetInvocationList().Length > 0)
                Update(file.FullName, ((FileInfo)file).Length);
        }
        else
            throw new IOException("invalid file or folder");
    }

    参考文章:http://www.codeproject.com/KB/miscctrl/ISOImage.aspx?msg=2464574

    更多的ISO制作的功能请参考How to Create Optical File Images using IMAPIv2.0How to Burn Optical File Images with IMAPI 2.0 from Managed Code

  • 相关阅读:
    [UVA100] The 3n + 1 problem.题解
    [SP1] TEST
    LCA【模板】
    [P1000] 超级玛丽游戏.题解
    [P3367]【模板】并查集.题解
    并查集【模板】
    洛谷 P1890 【gcd区间】
    浅谈分块算法经典问题&优化
    Floyd算法详(cha)解
    逆序对
  • 原文地址:https://www.cnblogs.com/xuesong/p/1793658.html
Copyright © 2011-2022 走看看