繁体   English   中英

SSIS脚本任务中String Builder的System.out of memory异常

[英]System.out of Memory Exception for String Builder in SSIS Script Task

我在SSIS脚本任务中使用VB脚本将标头和尾部添加到平面文件中。 代码运行良好,直到最近我遇到了一个问题,文件中的行比平时多,导致脚本任务失败,并显示错误`Error:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
   at System.String.GetStringForStringBuilder(String value, Int32 startIndex, Int32 length, Int32 capacity)
   at System.Text.StringBuilder.GetNewString(String currentString, Int32 requiredLength)
   at System.Text.StringBuilder.Append(Char[] value, Int32 startIndex, Int32 charCount)
   at System.IO.StreamReader.ReadToEnd()
   at System.IO.File.ReadAllText(String path, Encoding encoding)
   at System.IO.File.ReadAllText(String path)`

任何人都可以帮助我解决问题。我认为我需要使用其他与字符串相关的方法来代替“ String Builder”。 我在fileContents.Append(File.ReadAllText(Dts.Connections(“ DestinationConnection”)。ConnectionString))时遇到错误

这是我的代码:

Public Sub Main()

    Dim fileContents As New StringBuilder()
    Dim finalfile As String
    Dim firstline As String
    Dim lastline As String


    Dts.VariableDispenser.LockForRead("FirstLine")
    Dts.VariableDispenser.LockForRead("LastLine")

    Dts.VariableDispenser.LockForRead("FileName")

    firstline = CType(Dts.Variables("FirstLine").Value, String)
    finalfile = CType(Dts.Variables("FileName").Value, String)
    lastline= CType(Dts.Variables("LastLine").Value, String)


    'Write header, then append file contents and write back out.
    fileContents.AppendLine(String.Format("{0}", firstline))
      fileContents.Append(File.ReadAllText(Dts.Connections("DestinationConnection").ConnectionString))
    fileContents.AppendLine(String.Format("{0}", lastline))

    File.WriteAllText(finalfile, fileContents.ToString())

    Dts.TaskResult = ScriptResults.Success
End Sub

好吧,一个简单的方法就是避免StringBuilder :使用File.CreateText打开TextWriter ,写第一行,然后写File.ReadAllText(...) ,然后写最后一行。

但是,这只会节省您一些内存-它将大致减少所需的内存,因为在StringBuilder 字符串中都不需要它(我认为现在会发生这种情况)。

更好的选择是:

  • 打开作家
  • 写标题行
  • 打开另一个文件进行读取
    • 循环遍历文件,一次读取一大堆字符并将其写入新文件,直到完成
    • 隐式关闭另一个文件(为此使用Using语句)
  • 写尾线
  • 隐式关闭写操作(使用Using语句)

这样,即使您有大量文件,也一次只需要一小部分数据在内存中。

问题是File.ReadAllText在读取大文件时有局限性,因为整个文件都已读入内存。

您需要做的是将File.ReadAllText替换为逐行读取文件,并相应地附加它。

编辑示例:

Option Explicit
Dim oFSO, sFile, oFile, sText
Set oFSO = CreateObject("Scripting.FileSystemObject")
sFile = "your text file"
If oFSO.FileExists(sFile) Then
    Set oFile = oFSO.OpenTextFile(sFile, 1)
    Do While Not oFile.AtEndOfStream
        sText = oFile.ReadLine
        If Trim(sText) <> "" Then
            fileContents.AppendLine(sText)
        End If
    Loop
    oFile.Close
Else
    WScript.Echo "The file was not there."
End If

fileContents StringBuilder可能仍然存在问题。 虽然显示的原始错误是从File.ReadAllText方法引发的。 因此,希望能达到目的。

如果没有,我只会忘记fileContents StringBuilder并写出标题。 然后逐行从文件中读取并逐行将其写出,最后写入页脚。

另一种替代方法(以及更多类似SSIS的解决方案)是创建一个数据流任务,该任务读取现有文件,通过添加了页眉和页脚的脚本组件将其通过管道传输,并将其写入文件系统。 这是SSIS 2005中的外观:

在此处输入图片说明

脚本组件将是一个转换,其输出的SynchronousInputID设置为False,以便它可以生成页眉和页脚行:

在此处输入图片说明

转换的VB源应如下所示:

Public Class ScriptMain
    Inherits UserComponent
    Dim headerWritten As Boolean = False

    Public Overrides Sub IncomingRows_ProcessInputRow(ByVal Row As IncomingRowsBuffer)
        If Not headerWritten Then
            WriteHeader()
        End If
        OutgoingRowsBuffer.AddRow()
        OutgoingRowsBuffer.theLine = Row.theLine 
    End Sub

    Public Overrides Sub FinishOutputs()
        MyBase.FinishOutputs()
        WriteFooter()
    End Sub

    Private Sub WriteHeader()
        OutgoingRowsBuffer.AddRow()
        OutgoingRowsBuffer.theLine = "The First Header Line"
        headerWritten = True
    End Sub

    Private Sub WriteFooter()
        OutgoingRowsBuffer.AddRow()
        OutgoingRowsBuffer.theLine = "Here's a footer line"
        OutgoingRowsBuffer.AddRow()
        OutgoingRowsBuffer.theLine = "Here's another one"
    End Sub
End Class

这样,您就可以利用SSIS的流功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM