code: private void loadCSVFromReader(TableDefinition  tableDef,
                                     String           csvName,
                                     long             byteLength,
                                     BufferedReader   reader) {
          m_logger.info("Loading CSV file: {}", csvName);
          
          // Determine the order in which fields in this file appear. Wrap this in a CSVFile.
          List<String> fieldList = getFieldListFromHeader(reader);
          CSVFile csvFile = new CSVFile(csvName, tableDef, fieldList);
          
          long startTime = System.currentTimeMillis();
          long recsLoaded = 0;
          int lineNo = 0;
              while (true) {
                  Map<String, String> fieldMap = new HashMap<String, String>();
                  if (!tokenizeCSVLine(csvFile, reader, fieldMap)) {
                      break;
                  }
                  lineNo++;
                  m_totalLines++;
                  
                  try {
                      m_workerQueue.put(new Record(csvFile, fieldMap));
                  } catch (InterruptedException e) {
                      logErrorThrow("Error posting to queue", e.toString());
                  }
                  if ((++recsLoaded % 10000) == 0) {
                      m_logger.info("...loaded {} records.", recsLoaded);
                  }
              }
              
          // Always close the file and display stats even if an error occurred.
          m_totalFiles++;
          m_totalBytes += byteLength;
          long stopTime = System.currentTimeMillis();
          long totalMillis = stopTime - startTime;
          if (totalMillis == 0) {
              totalMillis = 1;    // You never know
          }
          m_logger.info("File '{}': time={} millis; lines={}",
                        new Object[]{csvFile.m_fileName, totalMillis, lineNo});
      }
docs: CSVFile. The caller must pass an opened stream and close it.