github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/encoding/csv/reader.go (about)

     1  // Copyright 2011 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // csvパッケージは、カンマ区切り値(CSV)ファイルを読み書きします。
     6  // 多種多様なCSVファイルがありますが、このパッケージはRFC 4180で説明されている形式をサポートしています。
     7  //
     8  // CSVファイルには、レコードごとに1つ以上のフィールドを含むゼロ以上のレコードが含まれています。
     9  // 各レコードは改行文字で区切られます。最後のレコードはオプションで改行文字に続くことができます。
    10  //
    11  //	field1,field2,field3
    12  //
    13  // 空白はフィールドの一部と見なされます。
    14  //
    15  // 改行文字の前のキャリッジリターンは、静かに削除されます。
    16  //
    17  // 空行は無視されます。空白文字のみで構成される行(末尾の改行文字を除く)は、空行と見なされません。
    18  //
    19  // クォート文字 "で始まり、終わるフィールドは、クォートフィールドと呼ばれます。
    20  // 開始と終了の引用符はフィールドの一部ではありません。
    21  //
    22  // ソース:
    23  //
    24  //	normal string,"quoted-field"
    25  //
    26  // は、次のフィールドを生成します。
    27  //
    28  //	{`normal string`, `quoted-field`}
    29  //
    30  // クォートフィールド内の引用符の後に2番目の引用符が続く場合、
    31  // 1つの引用符として扱われます。
    32  //
    33  //	"the ""word"" is true","a ""quoted-field"""
    34  //
    35  // の結果は次のとおりです。
    36  //
    37  //	{`the "word" is true`, `a "quoted-field"`}
    38  //
    39  // 改行とカンマは、クォートフィールド内に含めることができます。
    40  //
    41  //	"Multi-line
    42  //	field","comma is ,"
    43  //
    44  // の結果は次のとおりです。
    45  //
    46  //	{`Multi-line
    47  //	field`, `comma is ,`}
    48  package csv
    49  
    50  import (
    51  	"github.com/shogo82148/std/bufio"
    52  	"github.com/shogo82148/std/errors"
    53  	"github.com/shogo82148/std/io"
    54  )
    55  
    56  // ParseErrorは、解析エラーの場合に返されます。
    57  // 行番号と行番号は1から始まります。
    58  type ParseError struct {
    59  	StartLine int
    60  	Line      int
    61  	Column    int
    62  	Err       error
    63  }
    64  
    65  func (e *ParseError) Error() string
    66  
    67  func (e *ParseError) Unwrap() error
    68  
    69  // [ParseError.Err] で返される可能性のあるエラーです。
    70  var (
    71  	ErrBareQuote  = errors.New("bare \" in non-quoted-field")
    72  	ErrQuote      = errors.New("extraneous or missing \" in quoted-field")
    73  	ErrFieldCount = errors.New("wrong number of fields")
    74  
    75  	// Deprecated: ErrTrailingComma はもう使用されません。
    76  	ErrTrailingComma = errors.New("extra delimiter at end of line")
    77  )
    78  
    79  // Readerは、CSVエンコードされたファイルからレコードを読み取ります。
    80  //
    81  // [NewReader] によって返された場合、ReaderはRFC 4180に準拠した入力を想定しています。
    82  // 最初の [Reader.Read] または [Reader.ReadAll] 呼び出しの前に、エクスポートされたフィールドを変更して詳細をカスタマイズできます。
    83  //
    84  // Readerは、入力のすべての\r\nシーケンスをプレーンな\nに変換するため、
    85  // 複数行のフィールド値を含む場合でも、返されるデータが入力ファイルが使用する行末の規約に依存しないようにします。
    86  type Reader struct {
    87  	// Commaはフィールドの区切り文字です。
    88  	// NewReaderによってカンマ(',')に設定されます。
    89  	// Commaは有効なルーンである必要があり、\r、\n、
    90  	// またはUnicode置換文字(0xFFFD)であってはなりません。
    91  	Comma rune
    92  
    93  	// Commentが0でない場合、Comment文字はコメント文字です。
    94  	// 先行する空白がないComment文字で始まる行は無視されます。
    95  	// 先行する空白がある場合、TrimLeadingSpaceがtrueであっても、Comment文字はフィールドの一部になります。
    96  	// Commentは有効なルーンである必要があり、\r、\n、
    97  	// またはUnicode置換文字(0xFFFD)であってはなりません。
    98  	// また、Commaと等しくてはなりません。
    99  	Comment rune
   100  
   101  	// FieldsPerRecordは、レコードごとに期待されるフィールド数です。
   102  	// FieldsPerRecordが正の場合、Readは各レコードが指定されたフィールド数を持つことを要求します。
   103  	// FieldsPerRecordが0の場合、Readは最初のレコードのフィールド数に設定し、
   104  	// 以降のレコードは同じフィールド数を持つ必要があります。
   105  	// FieldsPerRecordが負の場合、チェックは行われず、レコードは可変長のフィールド数を持つ場合があります。
   106  	FieldsPerRecord int
   107  
   108  	// LazyQuotesがtrueの場合、引用符は引用符で囲まれていないフィールドに表示される場合があります。
   109  	LazyQuotes bool
   110  
   111  	// TrimLeadingSpaceがtrueの場合、フィールドの先頭の空白は無視されます。
   112  	// これは、フィールド区切り文字であるCommaが空白である場合でも行われます。
   113  	TrimLeadingSpace bool
   114  
   115  	// ReuseRecordは、パフォーマンスのために、Readの呼び出しが前回の呼び出しの返されたスライスのバッキング配列を共有するスライスを返すかどうかを制御します。
   116  	// デフォルトでは、Readの各呼び出しは、呼び出し元が所有する新しく割り当てられたメモリを返します。
   117  	ReuseRecord bool
   118  
   119  	// Deprecated: TrailingComma はもう使用されません。
   120  	TrailingComma bool
   121  
   122  	r *bufio.Reader
   123  
   124  	// numLine is the current line being read in the CSV file.
   125  	numLine int
   126  
   127  	// offset is the input stream byte offset of the current reader position.
   128  	offset int64
   129  
   130  	// rawBuffer is a line buffer only used by the readLine method.
   131  	rawBuffer []byte
   132  
   133  	// recordBuffer holds the unescaped fields, one after another.
   134  	// The fields can be accessed by using the indexes in fieldIndexes.
   135  	// E.g., For the row `a,"b","c""d",e`, recordBuffer will contain `abc"de`
   136  	// and fieldIndexes will contain the indexes [1, 2, 5, 6].
   137  	recordBuffer []byte
   138  
   139  	// fieldIndexes is an index of fields inside recordBuffer.
   140  	// The i'th field ends at offset fieldIndexes[i] in recordBuffer.
   141  	fieldIndexes []int
   142  
   143  	// fieldPositions is an index of field positions for the
   144  	// last record returned by Read.
   145  	fieldPositions []position
   146  
   147  	// lastRecord is a record cache and only used when ReuseRecord == true.
   148  	lastRecord []string
   149  }
   150  
   151  // NewReaderは、rから読み取る新しいReaderを返します。
   152  func NewReader(r io.Reader) *Reader
   153  
   154  // Readはrから1つのレコード(フィールドのスライス)を読み込みます。
   155  // レコードに予期しない数のフィールドが含まれている場合、
   156  // Readはエラー [ErrFieldCount] とともにレコードを返します。
   157  // パースできないフィールドが含まれている場合、
   158  // Readは部分的なレコードとパースエラーを返します。
   159  // 部分的なレコードには、エラーが発生する前に読み取られたすべてのフィールドが含まれます。
   160  // 読み取るデータがない場合、Readはnil、io.EOFを返します。
   161  // [Reader.ReuseRecord] がtrueの場合、返されるスライスは複数のRead呼び出し間で共有できます。
   162  func (r *Reader) Read() (record []string, err error)
   163  
   164  // FieldPosは、Readで最後に返されたスライス内の指定されたインデックスのフィールドの開始に対応する行と列を返します。
   165  // 行と列の番号付けは1から始まります。列はルーンではなくバイトで数えられます。
   166  //
   167  // インデックスが範囲外で呼び出された場合、panicします。
   168  func (r *Reader) FieldPos(field int) (line, column int)
   169  
   170  // InputOffsetは、現在のリーダーの位置の入力ストリームバイトオフセットを返します。
   171  // オフセットは、最後に読み取られた行の終わりと次の行の始まりの場所を示します。
   172  func (r *Reader) InputOffset() int64
   173  
   174  // ReadAllは、rから残りのすべてのレコードを読み込みます。
   175  // 各レコードはフィールドのスライスです。
   176  // 成功した呼び出しはerr == nilを返します。err == [io.EOF] ではありません。
   177  // ReadAllはEOFまで読み込むように定義されているため、エラーとして扱いません。
   178  func (r *Reader) ReadAll() (records [][]string, err error)