public boolean makeIndex(String filename, RandomAccessFile dataRaf) throws IOException {
    String idxPath = filename;
    if (!idxPath.endsWith(GBX9_IDX)) idxPath += GBX9_IDX;
    File idxFile = GribIndexCache.getFileOrCache(idxPath);
    File idxFileTmp = GribIndexCache.getFileOrCache(idxPath + ".tmp");

    RandomAccessFile raf = null;
    try (FileOutputStream fout = new FileOutputStream(idxFileTmp)) {
      //// header message
      fout.write(MAGIC_START.getBytes(CDM.utf8Charset));
      NcStream.writeVInt(fout, version);

      Map<Long, Integer> gdsMap = new HashMap<>();
      gdsList = new ArrayList<>();
      records = new ArrayList<>(200);

      Grib1IndexProto.Grib1Index.Builder rootBuilder = Grib1IndexProto.Grib1Index.newBuilder();
      rootBuilder.setFilename(filename);

      if (dataRaf == null)  { // open if dataRaf not already open
        raf = RandomAccessFile.acquire(filename);
        dataRaf = raf;
      }

      Grib1RecordScanner scan = new Grib1RecordScanner(dataRaf);
      while (scan.hasNext()) {
        Grib1Record r = scan.next();
        if (r == null) break; // done
        records.add(r);

        Grib1SectionGridDefinition gdss = r.getGDSsection();
        Integer index = gdsMap.get(gdss.calcCRC());
        if (gdss.getPredefinedGridDefinition() >= 0) // skip predefined gds - they dont have raw bytes
          index = 0;
        else if (index == null) {
          gdsList.add(gdss);
          index = gdsList.size() - 1;
          gdsMap.put(gdss.calcCRC(), index);
          rootBuilder.addGdsList(makeGdsProto(gdss));
        }
        rootBuilder.addRecords(makeRecordProto(r, index));
      }

      if (records.isEmpty())
        throw new RuntimeException("No GRIB1 records found in "+dataRaf.getLocation());

      ucar.nc2.grib.grib1.Grib1IndexProto.Grib1Index index = rootBuilder.build();
      byte[] b = index.toByteArray();
      NcStream.writeVInt(fout, b.length); // message size
      fout.write(b);  // message  - all in one gulp
      logger.debug("  made gbx9 index for {} size={}", filename, b.length);
      return true;

    } finally {
      if (raf != null) raf.close();   // only close if it was opened here

            // now switch
      RandomAccessFile.eject(idxFile.getPath());
      boolean deleteOk = !idxFile.exists() || idxFile.delete();
      boolean renameOk = idxFileTmp.renameTo(idxFile);
      if (!deleteOk)
        logger.error("  could not delete Grib1Index= {}", idxFile.getPath());
      if (!renameOk)
        logger.error("  could not rename Grib1Index= {}", idxFile.getPath());
    }
  }
public boolean makeIndex(String filename, RandomAccessFile dataRaf) throws IOException {
    String idxPath = filename;
    if (!idxPath.endsWith(GBX9_IDX)) idxPath += GBX9_IDX;
    File idxFile = GribIndexCache.getFileOrCache(idxPath);
    File idxFileTmp = GribIndexCache.getFileOrCache(idxPath + ".tmp");

    RandomAccessFile raf = null;
    try (FileOutputStream fout = new FileOutputStream(idxFileTmp)) {
      
      fout.write(MAGIC_START.getBytes(CDM.utf8Charset));
      NcStream.writeVInt(fout, version);

      Map<Long, Integer> gdsMap = new HashMap<>();
      gdsList = new ArrayList<>();
      records = new ArrayList<>(200);

      Grib1IndexProto.Grib1Index.Builder rootBuilder = Grib1IndexProto.Grib1Index.newBuilder();
      rootBuilder.setFilename(filename);

      if (dataRaf == null)  { 
        raf = RandomAccessFile.acquire(filename);
        dataRaf = raf;
      }

      Grib1RecordScanner scan = new Grib1RecordScanner(dataRaf);
      while (scan.hasNext()) {
        Grib1Record r = scan.next();
        if (r == null) break; 
        records.add(r);

        Grib1SectionGridDefinition gdss = r.getGDSsection();
        Integer index = gdsMap.get(gdss.calcCRC());
        if (gdss.getPredefinedGridDefinition() >= 0) 
          index = 0;
        else if (index == null) {
          gdsList.add(gdss);
          index = gdsList.size() - 1;
          gdsMap.put(gdss.calcCRC(), index);
          rootBuilder.addGdsList(makeGdsProto(gdss));
        }
        rootBuilder.addRecords(makeRecordProto(r, index));
      }

      if (records.isEmpty())
        throw new RuntimeException("No GRIB1 records found in "+dataRaf.getLocation());

      ucar.nc2.grib.grib1.Grib1IndexProto.Grib1Index index = rootBuilder.build();
      byte[] b = index.toByteArray();
      NcStream.writeVInt(fout, b.length); 
      fout.write(b);  
      logger.debug("  made gbx9 index for {} size={}", filename, b.length);
      return true;

    } finally {
      if (raf != null) raf.close();   

            
      RandomAccessFile.eject(idxFile.getPath());
      boolean deleteOk = !idxFile.exists() || idxFile.delete();
      boolean renameOk = idxFileTmp.renameTo(idxFile);
      if (!deleteOk)
        logger.error("  could not delete Grib1Index= {}", idxFile.getPath());
      if (!renameOk)
        logger.error("  could not rename Grib1Index= {}", idxFile.getPath());
    }
  }
public boolean makeIndex ( String filename , RandomAccessFile dataRaf ) throws IOException { String idxPath = filename ; if ( ! idxPath . endsWith ( GBX9_IDX ) ) idxPath += GBX9_IDX ; File idxFile = GribIndexCache . getFileOrCache ( idxPath ) ; File idxFileTmp = GribIndexCache . getFileOrCache ( idxPath + ".tmp" ) ; RandomAccessFile raf = null ; try ( FileOutputStream fout = new FileOutputStream ( idxFileTmp ) ) { //// header message
 fout . write ( MAGIC_START . getBytes ( CDM . utf8Charset ) ) ; NcStream . writeVInt ( fout , version ) ; Map < Long , Integer > gdsMap = new HashMap <> ( ) ; gdsList = new ArrayList <> ( ) ; records = new ArrayList <> ( 200 ) ; Grib1IndexProto . Grib1Index . Builder rootBuilder = Grib1IndexProto . Grib1Index . newBuilder ( ) ; rootBuilder . setFilename ( filename ) ; if ( dataRaf == null ) { // open if dataRaf not already open
 raf = RandomAccessFile . acquire ( filename ) ; dataRaf = raf ; } Grib1RecordScanner scan = new Grib1RecordScanner ( dataRaf ) ; while ( scan . hasNext ( ) ) { Grib1Record r = scan . next ( ) ; if ( r == null ) break ; // done
 records . add ( r ) ; Grib1SectionGridDefinition gdss = r . getGDSsection ( ) ; Integer index = gdsMap . get ( gdss . calcCRC ( ) ) ; if ( gdss . getPredefinedGridDefinition ( ) >= 0 ) // skip predefined gds - they dont have raw bytes
 index = 0 ; else if ( index == null ) { gdsList . add ( gdss ) ; index = gdsList . size ( ) - 1 ; gdsMap . put ( gdss . calcCRC ( ) , index ) ; rootBuilder . addGdsList ( makeGdsProto ( gdss ) ) ; } rootBuilder . addRecords ( makeRecordProto ( r , index ) ) ; } if ( records . isEmpty ( ) ) throw new RuntimeException ( "No GRIB1 records found in " + dataRaf . getLocation ( ) ) ; ucar . nc2 . grib . grib1 . Grib1IndexProto . Grib1Index index = rootBuilder . build ( ) ; byte [ ] b = index . toByteArray ( ) ; NcStream . writeVInt ( fout , b . length ) ; // message size
 fout . write ( b ) ; // message  - all in one gulp
 logger . debug ( "  made gbx9 index for {} size={}" , filename , b . length ) ; return true ; } finally { if ( raf != null ) raf . close ( ) ; // only close if it was opened here
 // now switch
 RandomAccessFile . eject ( idxFile . getPath ( ) ) ; boolean deleteOk = ! idxFile . exists ( ) || idxFile . delete ( ) ; boolean renameOk = idxFileTmp . renameTo ( idxFile ) ; if ( ! deleteOk ) logger . error ( "  could not delete Grib1Index= {}" , idxFile . getPath ( ) ) ; if ( ! renameOk ) logger . error ( "  could not rename Grib1Index= {}" , idxFile . getPath ( ) ) ; } }
LOOK what about extending an index ??
LOOK what about extending an index ??