2011-10-21 18 views
0

SSISスクリプトタスクでVBスクリプトを使用して、ヘッダーとトレーラーをフラットファイルに追加しています。最近、私は、ファイル内の行が通常よりもされている問題に出くわしたとerror`Errorとスクリプトタスクの障害になるまで、コードが正常に動作したSystem.out of memory SSISスクリプトの文字列ビルダーの例外タスク

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)`

いずれかが固定で私を助けることができます私は他の文字列関連のメソッドを使用する必要があります "文字列ビルダー"の代わりに思う。私はここで 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 

答えて

3

まあ、1つの簡単な方法はになりますちょうどを避けてくださいStringBuilderを開きます:TextWriterFile.CreateTextで開き、最初の行を書き込んでからFile.ReadAllText(...)と書き、最後の行を書きます。あなたは私がが起こるだろうと思い何である(StringBuilder文字列の両方でそれを必要としないので、それは大体、必要なメモリを半減します - だけあなたに一部メモリを節約しますが

、今)。 、ヘッダ行

  • ファイルを開く上で
    • ループを読み取るための他のファイルを書くのチャンクを読み込む

      • オープンライター
      • Aはるかに良い選択肢はになりますあなたが完了するまで、文字を一度に書き込んで新しいファイルに書き込みます。

      • 暗黙のうちに他のファイルを閉じます(これにはUsingステートメントを使用してください)。
    • あなたは巨大なファイルを持っている方法も、あなただけのメモリ内のデータの小さなチャンクが必要であることを

    Usingステートメントを使用)、暗黙的に書き込みを閉じ、末尾の行

  • を書きます一度に。

  • 1

    File.ReadAllTextは、ファイル全体がメモリに読み込まれるため、大きなファイルを読み込む場合に制限があります。

    あなたがする必要があるのは、File.ReadAllTextを1行ずつ読み込んでそれに応じて追加することです。例えば

    EDITED:あなたはまだFILECONTENTSのStringBuilderに問題がある可能性があり

    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 
    

    それが可能です。 File.ReadAllTextメソッドからスローされた元のエラー。だからうまくいけば、これはトリックです。

    もしそうでなければ、私はfileContents StringBuilderを一括して忘れてヘッダーを書き出します。その後、ファイルを1行ずつ読み込んで1行ずつ書き出し、最後にフッターを書きます。

    +0

    あなたは、コードiamで理解しようとしていますが、私は同じエラーtahnksを取得しています。 – lch

    +0

    私はちょうど私が見つけたスクリプトを編集しています。それが役立つかどうかを見てください。 – Josh

    0

    既存のファイルを読み込んで、ヘッダーとフッターを追加するスクリプトコンポーネントをパイプして、ファイルシステムに書き込むデータフロータスクを作成する方法もあります(SSISに似ています)。ここでは、SSIS 2005年にどのように見えるかです:

    :それはヘッダとフッタ行を生成することができるように

    enter image description here

    は、スクリプトコンポーネントは、Falseに設定され、その出力のSynchronousInputIDと変換されますenter image description here

    そして変換の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のストリーミング機能を利用することができます。