8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

libzip 函数返回成功但不执行任何操作

Mark Hurd 2月前

21 0

[编辑] 通过在调试器中逐步检查库源代码,我发现了一些可以帮助我解决这个问题的方法。zip_open() 函数实际上并没有创建文件,它只是保存......

[编辑] 通过在我的调试器中逐步检查库源,我发现了一些可以帮助我解决这个问题的方法。

  1. zip_open() 函数实际上并不创建文件,它只是保存名称以供稍后使用 zip_close() 。如果当前目录在处理过程中发生更改,并且 在调用之前 zip_close() ,则将直接在上次设置为当前的位置创建 ZIP 文件。恕我直言,这是库中的一个错误——如果调用中没有给出路径 zip_open() ,则应将当前目录添加到已保存的 ZIP 文件名前面,以供稍后(正确)使用 zip_close() .
  2. 通过删除驱动器号并从所有文件夹和文件名中保留反斜杠,我获得了更好的运气, 传递给的文件名 除外 zip_source_file() ,它需要知道完全限定路径。但如果 zip_file_add() 主要 C:\ 开头没有 (或其他), 似乎效果会更好

[OP] 我正在尝试学习如何在 Windows 11 上使用 Visual Studio 2022 和 C 使用 libzip 创建 ZIP 文件。完成后,我的文件应该在多个不同的文件夹中包含多个文件。这是我的最终目标。现在,我只想创建一个 ZIP 文件,但该库并没有帮助我正确使用它,因为它没有返回错误,即使它无法执行我要求它执行的任何操作(可检测到)。我不是在寻求帮助来修复我的代码(尽管我当然不会拒绝![微笑]),我真正想在这里学习的是如何使用一个即使明显失败也会返回成功的库来调试问题。

如果我仅使用这个基本序列(已 _UseFqn_ 定义)和完全限定的路径/文件名( fqn ),那么实际上就会创建一个 ZIP(Windows 不会读取它,但 7-Zip 可以,所以目前没问题):

zip_open()
zip_source_file(fqn)
zip_file_add(fqn)
zip_close()

如果我习惯 SetCurrentDirectory() 更改为实际包含每个文件的文件夹( fpath ),并尝试添加没有路径信息的文件( fname ),那么我 不会收到任何错误 ,但也不会得到 任何 zip 文件

zip_open()
SetCurrentDirectory(fpath)
zip_source_file(fname)
zip_file_add(fname)
zip_close()

如果我尝试使用 添加目录 zip_dir_add() ,上述任一序列都不会出现错误,也不会生成 zip 文件。抱歉这篇文章太长了,但我也要添加我的测试源代码。请对此做一个假设:调用 _MakeZipFile() 的程序是这样调用的: _MakeZipFile("testfile.zip","C:\path\to\file\something.log\0");

//-------------------------------------------------------------------------
// Add a single file to the zip
static int _AddFileToZip( zip_t *zipFile, char *szFileName )
{
   int            rc = NO_ERROR;
   zip_source_t  *source;

   source = zip_source_file( zipFile, szFileName, 0, ZIP_LENGTH_TO_END );
   if( source == NULL )
   {
      printf( "ZipTest>  Failed to src file for zip:  '%s'...\n", szFileName );
      printf( "ZipTest>  libzip:  %s\n", zip_strerror( zipFile ) );
      rc = ERROR_INVALID_PARAMETER;
   }
   else if( zip_file_add( zipFile, szFileName, source, ZIP_FL_ENC_RAW ) < 0 )
   {
      zip_source_free( source );
      printf( "ZipTest>  Failed to add file to zip:  '%s'...\n", szFileName );
      printf( "ZipTest>  libzip:  %s\n", zip_strerror( zipFile ) );
      rc = ERROR_INVALID_FUNCTION;
   }
   else
   {  // print a diagnostic for debugging
      printf( "ZipTest>  added file:  '%s'...\n", szFileName );
   }
   return rc;
}

//-------------------------------------------------------------------------
// Add all folder levels, from top to bottom, recursively
static BOOL _AddFolderToZip( zip_t *zipFile, char *szFolder )
{
   char         sz[_MAX_PATH];
   char        *cp;
   BOOL         bResult;
   zip_error_t *pze;

   if( ':' == szFolder[1] )
   {  // Remove drive letter, if present
      szFolder += 2;
   }
   if( '\\' == *szFolder )
   {  // Remove leading backslash, if present
      szFolder++;
   }
   
   strcpy( sz, szFolder ); // copy so we don't trash the original
   cp = strrchr( sz, '\\' );
   if( cp && ('\0' == *(cp+1)) )
   {  // Remove trailing backslash
      *cp = '\0';
   }

   // Is this a sub-folder?
   cp = strrchr( sz, '\\' );
   if( cp && (cp != sz) )
   {  // Yes, call self to add parent first
      *cp = '\0';
      if( !_AddFolderToZip( zipFile, sz ) )
      {  // Failure, back out with errors
         return FALSE;
      }
      *cp = '\\';
   }

   // else No, time to add this folder.
   bResult = TRUE;
   if( zip_dir_add( zipFile, sz, ZIP_FL_ENC_RAW ) < 0 )
   {  // Error, but there's one error that is OK...
      pze = zip_get_error( zipFile );
      if( ZIP_ER_EXISTS != pze->zip_err )
      {  // Multiple files in same folder are OK.
         bResult = FALSE;
         printf( "ZipTest>  Failed to add directory to zip:  '%s'...\n", szFolder );
         printf( "ZipTest>  libzip:  %s\n", zip_strerror( zipFile ) );
      }
   }
   if( bResult )
   {  // print a diagnostic for debugging
      printf( "ZipTest>  added directory:  '%s'...\n", sz );
   }
   return bResult;
}

// ------------------------------------------------------------------------
#define _UseFqn_ 1   // Use Fully qualified file names and no directories
// comment this out to change directory, add the file folder, and add the filename
// ------------------------------------------------------------------------

// szzSourceList is a buffoer containing some number of NULL terminated
//               strings that ends with an empty string (i.e. double-NULL)
BOOL _MakeZipFile( char *szZipFileName, char *szzSourceList )
{
   BOOL              result = FALSE;
   int               errorp = NO_ERROR;
   zip_t            *zipFile;
   char             *cpFilePath;
   zip_error_t       ziperror;
   zip_error_t      *pze;
#if !defined(_UseFqn_)
   char              szDrive[_MAX_PATH];
   char              szPath[_MAX_PATH];
   char              szFile[_MAX_PATH];
   char              szExt[_MAX_PATH];
   char              szFolder[_MAX_PATH];
#endif
   char              szStartPath[_MAX_PATH];

   GetCurrentDirectory( sizeof(szStartPath), szStartPath );

   zipFile = zip_open( szZipFileName, ZIP_CREATE | ZIP_TRUNCATE, &errorp );
   if( zipFile == NULL )
   {
      zip_error_init_with_code( &ziperror, errorp );
      printf( "ZipTest>  Failed to open output file '%s'...\n", szZipFileName );
      printf( "ZipTest>  libzip:  %s\n", zip_error_strerror( &ziperror ) );
      return FALSE;
   }

   __try
   {
      cpFilePath = szzSourceList;
      while( *cpFilePath )
      {
#if defined(_UseFqn_)
         _AddFileToZip( zipFile, cpFilePath );
#else
         _splitpath( cpFilePath, szDrive, szPath, szFile, szExt );
         sprintf( szFolder, "%s%s", szDrive, szPath );
         SetCurrentDirectory( szFolder );
         _AddFolderToZip( zipFile, szPath );
         strcat( szFile, szExt );
         _AddFileToZip( zipFile, szFile );
#endif

         // Find next entry in \0\0 terminated string list
         while( *cpFilePath )
         {
            cpFilePath++;
         }
         cpFilePath++;
      }
   }
   __finally
   {
      if( NO_ERROR == zip_close( zipFile ) )
      {
         result = TRUE;
      }
      else
      {
         pze = zip_get_error( zipFile );
         printf( "ZipTest>  Failed to create output file '%s'...\n", szZipFileName );
         printf( "ZipTest>  libzip:  %s\n", zip_strerror( zipFile ) );
         printf( "ZipTest>  zip_err = %d   sys_err = %d\n", pze->zip_err, pze->sys_err );
      }
   }

   SetCurrentDirectory( szStartPath );

   return result;
}
帖子版权声明 1、本帖标题:libzip 函数返回成功但不执行任何操作
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Mark Hurd在本站《c》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 我注意到了这一点, zip_file_add() 也会 zip_source_file() 返回成功错误代码。这种行为让我感到惊讶,如果您希望将其传达为失败,我理解这令人沮丧。

    直接回答你的问题:

    如何调试一个库的问题,即使它明显失败了,也会返回成功

    如果有人认为库函数“明显失败”但它返回了成功代码,那么我会说有两种可能性:

    1. 库代码中有一个错误。
    2. 您对此处“成功”和“失败”的期望与图书馆作者的期望有所不同。

    使用开源库的好处是(理论上)您可以自己检查情况 1。从 记录的错误 源代码 ,我认为开发人员并不认为 \'fname\' 参数未指向文件时是故障模式。您甚至可以 向作者发送补丁来更新文档以使其更清晰。 而且他们似乎很活跃,所以可能会修复。

    对于您的函数的问题,我会尝试测试该文件是否存在并且是否可读(您可以使用 fopen(fname, "r") 它)然后再尝试将其添加到存档中 zip_source_file() .

  • 如果这个问题写得能让其他人重现,那么回答起来会更容易一些。我无法重现这个问题,因为

返回
作者最近主题: