VB.NET CSV読み書き汎用ユーティリティクラス例

2011/09/28 16:23Update
TAGS: VB.NET | CSV | 読み込み | 取り込み | 書き込み | Generic | ジェネリック

VB.NETのジェネリック機能を利用した、汎用性の高いCSV形式データの解析と出力を行うユーティリティクラスです。

コード例:
Imports Microsoft.VisualBasic
Imports System.Collections.Generic

Module CommonCsv
    ''' <summary>
    ''' ==== VB.NET CSVファイルの汎用処理クラス by Syboos.com ====
    ''' 
    ''' ヘッダ部すべてのコメントを削除しない条件で、このクラスを自由にご利用できます。
    ''' http://www.syboos.com
    ''' http://www.syboos.jp
    ''' ※フリー
    ''' ※再配布可
    ''' ※商用可
    ''' ※コードの一部編集・削除可
    ''' ※自己責任でご利用ください
    ''' 
    ''' CSV処理する汎用クラス
    ''' 
    ''' 使い方
    ''' 1)行データクラスを実装。例:
    ''' Public Class MyCsvRow 
    '''     name, value ...(詳細略)
    ''' End Class
    ''' 
    ''' 2)CsvRowProcessorから継承した一行のデータを処理するクラスを実装。例:
    ''' Public Class MyCsvRowProcessor(Of T As MyCsvRow) Inherits CsvRowProcessor(Of T)
    '''     Public Overrides Function rowData2Object(ByVal row As String()) As T
    '''         Dim ret As MyCsvRow = New MyCsvRow
    '''         'process row to ret HERE
    '''         Return ret
    '''     End Function
    ''' 
    '''     Public Overrides Function object2RowData(ByVal obj As T) As String()
    '''         'Dim row As MyCsvRow = obj
    '''         Return obj.toStringArray    'MyCsvRowにtoStringArrayメソッドを実装する必要があります。
    '''     End Function
    ''' End Class
    ''' 
    ''' 3)CommonCsv呼び出し。例
    ''' Dim rowProcessor As MyCsvRowProcessor(Of MyCsvRow) = New MyCsvRowProcessor(Of MyCsvRow)
    ''' Dim commonCsv As CommonCsv(Of MyCsvRow) = New CommonCsv(Of MyCsvRow)(rowProcessor)
    ''' 
    ''' 'CSV読み込み
    ''' commonCsv.readFromInputStream(inputStream, encoding)
    ''' 
    ''' 'CSV書き込み
    ''' commonCsv.writeToCsv(outputStream, encoding)
    ''' 
    ''' </summary>
    ''' <typeparam name="T">行データを処理するクラス</typeparam>
    Public Class CommonCsv(Of T)
        Dim list As List(Of T) = New List(Of T)         '行データを格納するリスト
        Dim rowProcessor As CsvRowProcessor(Of T)       '行データを処理するクラス

        Public Sub New(ByVal rowProcessor As CsvRowProcessor(Of T))
            Me.rowProcessor = rowProcessor
        End Sub


        ''' <summary>
        '''  CSV入力ストリームからデータを読み込み
        ''' </summary>
        ''' <param name="inputStream">System.IO.Stream</param>
        ''' <param name="encoding">文字コード</param>
        Public Sub readFromInputStream(ByVal inputStream As System.IO.Stream, ByVal encoding As String)
            '入力ストリームからデータを読み込み
            Dim parser As New FileIO.TextFieldParser(inputStream, System.Text.Encoding.GetEncoding(encoding))

            parser.TextFieldType = FileIO.FieldType.Delimited
            parser.SetDelimiters(",")
            parser.HasFieldsEnclosedInQuotes = True
            parser.TrimWhiteSpace = False

            '最後まで読み込み
            While Not parser.EndOfData
                Dim row As String() = parser.ReadFields() ' 1行読み込み

                Dim rowObj As T = rowProcessor.rowData2Object(row)  '一行のデータを処理
                If (Not rowObj Is Nothing) Then
                    list.Add(rowObj)        'データをlist変数に追加
                End If

            End While
        End Sub

        ''' <summary>
        ''' 一行のデータを追加
        ''' </summary>
        ''' <param name="row">行データ</param>
        Public Sub addRow(ByVal row As T)
            list.Add(row)
        End Sub

        ''' <summary>
        ''' すべての行のデータを取得
        ''' </summary>
        Public Function getRowList() As List(Of T)
            Return list
        End Function

        ''' <summary>
        ''' CSVへの出力
        ''' </summary>
        ''' <param name="outputStream">System.IO.Stream</param>
        ''' <param name="encoding">文字コード</param>
        ''' <remarks></remarks>
        Public Sub writeToCsv(ByVal outputStream As System.IO.Stream, ByVal encoding As String)
            Dim enc As System.Text.Encoding = System.Text.Encoding.GetEncoding(encoding)
            Dim streamWriter As New System.IO.StreamWriter(outputStream, enc)

            streamWriter.AutoFlush = True
            Try
                For Each rowObj As T In list    '一行ずつ処理
                    '一行出力(行データをStringの配列に変更)
                    Dim outputRow As String() = rowProcessor.object2RowData(rowObj)  '一行データ:String配列へ変更

                    writeLine(outputRow, streamWriter)                      '一行を出力
                    streamWriter.Write(ControlChars.Cr + ControlChars.Lf)   '改行
                Next
            Catch ex As Exception
                Throw ex
            Finally
                streamWriter.Flush()
                streamWriter.Close()
            End Try

        End Sub

        Private Sub writeLine(ByVal outputRow As String(), ByVal streamWriter As System.IO.StreamWriter)
            Dim first As Boolean = True
            For Each field As String In outputRow
                field = """" + field + """"
                If (first) Then
                    streamWriter.Write(field)
                    first = False
                Else
                    streamWriter.Write("," + field)
                End If
            Next
        End Sub

    End Class




    ''' <summary>
    ''' 行データを処理するクラス。このクラスを継承してご利用ください。
    ''' 1)一行をあらわすObjectからString配列に変更
    ''' 2)String配列から一行をあらわすObjectに変更
    ''' </summary>
    ''' <typeparam name="T"></typeparam>
    ''' <remarks></remarks>
    Public Class CsvRowProcessor(Of T)
        'String配列から一行をあらわすObjectに変更
        Public Overridable Function rowData2Object(ByVal row As String()) As T
            Throw New Exception("This method must be overrided.")
        End Function

        '一行をあらわすObjectからString配列に変更
        Public Overridable Function object2RowData(ByVal obj As T) As String()
            Throw New Exception("This method must be overrided.")
        End Function
    End Class
End Module

.

有关作者
Syboos.jp編集長AJavaやオープンソース情報の執筆、Webサイトの開発や運営全般の業務に携わる。

Sponsored Link


Comments

用户名 (required)

Email (will not be published) (required)

URL

Evaluation