VB.Net SSIS Script Task验证Zip文件时Try-Catch仅对首个损坏文件生效求解
解决方案
1. 完全可以用Try-Catch实现需求,你之前的问题是资源未正确释放导致
你遇到的第二个损坏文件不触发异常的问题,根源是抛出异常时ZipArchive对象没有执行Dispose操作,非托管资源残留,导致后续文件操作异常。不需要使用On Error Resume Next,该语法是VB6遗留实现,你遇到的处理耗时逐步变长就是资源泄漏未清理导致的,长期运行还可能出现进程崩溃问题,完全不推荐使用。
2. 修正后的代码实现
推荐直接合并校验和解压逻辑,减少重复IO开销,同时自动处理资源释放:
Imports System.IO Imports System.IO.Compression ' 遍历目录处理所有Zip文件的核心逻辑 Public Sub ProcessAllZipFiles(ByVal zipDir As String, ByVal extractDir As String) ' 获取目录下所有zip文件 Dim allZipPaths As String() = Directory.GetFiles(zipDir, "*.zip", SearchOption.TopDirectoryOnly) For Each zipPath In allZipPaths Dim currentExtractPath = Path.Combine(extractDir, Path.GetFileNameWithoutExtension(zipPath)) ' 提前清理已存在的解压目录,避免冲突 If Directory.Exists(currentExtractPath) Then Directory.Delete(currentExtractPath, True) End If Try ' 直接执行解压,静态方法内部自动处理资源释放 ZipFile.ExtractToDirectory(zipPath, currentExtractPath) ' 此处添加解压成功后的数据库导入逻辑 Console.WriteLine($"处理成功:{zipPath}") Catch ex As InvalidDataException Console.WriteLine($"跳过损坏压缩包:{zipPath}") ' 清理半截解压的冗余文件 If Directory.Exists(currentExtractPath) Then Directory.Delete(currentExtractPath, True) End If Catch ex As IOException Console.WriteLine($"跳过无法访问的文件:{zipPath},错误原因:{ex.Message}") Catch ex As Exception Console.WriteLine($"跳过处理失败的文件:{zipPath},错误原因:{ex.Message}") End Try ' 处理大体积压缩包时可添加以下两句主动回收资源,无性能负面影响 GC.Collect() GC.WaitForPendingFinalizers() Next End Sub
如果需要保留单独的合法性校验方法,使用Using语句保证资源自动释放:
Private Function IsValidZip(ByVal filePath As String) As Boolean Try ' Using语句无论是否抛出异常都会自动释放ZipArchive资源 Using zipArchive As ZipArchive = ZipFile.OpenRead(filePath) ' 遍历所有压缩条目触发内容校验,避免仅头部合法的损坏文件漏判 For Each entry In zipArchive.Entries Using entryStream = entry.Open() entryStream.ReadByte() End Using Next End Using Return True Catch ' 所有异常均判定为不合法 Return False End Try End Function
3. 无需修改SSIS控制流
不需要调整为每个文件调用一次Script Task,单Script Task遍历全目录的方案完全可行。如果需要更细粒度的错误控制(比如单个文件失败后触发特定告警分支),也可以配合Foreach循环容器实现单文件处理,两种方案都可以根据业务需求选择。
内容的提问来源于stack exchange,提问作者m_zardos
相关产品推荐
相关产品推荐

