Chinaunix首页 | 论坛 | 博客
  • 博客访问: 153978
  • 博文数量: 37
  • 博客积分: 2510
  • 博客等级: 少校
  • 技术积分: 380
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-13 18:49
文章分类

全部博文(37)

文章存档

2010年(1)

2009年(19)

2008年(17)

我的朋友

分类: WINDOWS

2009-07-06 13:34:21

最近研究chrome代码时,发现它的安装包使用7z,它的代码可以解压chrome.7z(Google提供的安装压缩包)。但是却无法解压我自己生成的“xxx.7z”。
相关的核心代码如下(截取部分)(lzma_util.cc):

if ((ret = SzExtract(&archiveStream.InStream, &db, i, &blockIndex,
                         &outBuffer, &outBufferSize, &offset, &outSizeProcessed,
                         &allocImp, &allocTempImp)) != SZ_OK) {
      break;
    }
    

    std::wstring wfileName(location);

    file_util::AppendToPath(&wfileName, UTF8ToWide(f->Name));

    // If archive entry is directory create it and move on to the next entry.

    if (f->IsDirectory) {
        file_util::CreateDirectory(wfileName);
      continue;
    }

    HANDLE hFile;
    std::wstring directory = file_util::GetDirectoryFromPath(wfileName);

    file_util::CreateDirectory(directory);
    //SHCreateDirectoryEx(NULL, directory.c_str(), NULL);

    hFile = CreateFile(wfileName.c_str(), GENERIC_WRITE, 0, NULL,
                       CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE) {
        LOG(ERROR) << " ret = GetLastError()3; ";
      ret = GetLastError();
      break;
    }


大概的逻辑是:
当file为目录时,创建目录。如果是文件,则首先提取文件所在的目录,并创建目录(如果不存在)。

但是经过查证发现,当使用自己的7z文件解压时,创建目录失败了。它创建目录的代码如下:
(file_util_win.cc)

bool CreateDirectory(const FilePath& full_path) {
  if (DirectoryExists(full_path))
    return true;
  int err = SHCreateDirectoryEx(NULL, full_path.value().c_str(), NULL);
  return err == ERROR_SUCCESS;
}


SHCreateDirectoryEx函数一个windows API。
最后发现SHCreateDirectoryEx只认得微软的"\\"路径分隔符,而不认识"/",所以在创建目录前将path中所有的"/"t替换成"\\"即可。

这里提供一个可用但不一定最佳的函数。

std::wstring& LzmaUtil::replace_all(std::wstring& str,const std::wstring& old_value,const std::wstring&new_value)
{
    while(true) {
        std::wstring::size_type pos(0);
        if((pos=str.find(old_value))!=std::wstring::npos )
            str.replace(pos,old_value.length(),new_value);
        else break;
    }
    return str;
}


(replace_all(path,L"/",L"\\");)
阅读(2501) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~