All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ucar.nc2.NetcdfFileWriteable Maven / Gradle / Ivy

Go to download

The NetCDF-Java Library is a Java interface to NetCDF files, as well as to many other types of scientific data formats.

The newest version!
/*
 * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
 *
 * Portions of this software were developed by the Unidata Program at the
 * University Corporation for Atmospheric Research.
 *
 * Access and use of this software shall impose the following obligations
 * and understandings on the user. The user is granted the right, without
 * any fee or cost, to use, copy, modify, alter, enhance and distribute
 * this software, and any derivative works thereof, and its supporting
 * documentation for any purpose whatsoever, provided that this entire
 * notice appears in all copies of the software, derivative works and
 * supporting documentation.  Further, UCAR requests that the user credit
 * UCAR/Unidata in any publications that result from the use of this
 * software or in any product that includes this software. The names UCAR
 * and/or Unidata, however, may not be used in any advertising or publicity
 * to endorse or promote any products or commercial entity unless specific
 * written permission is obtained from UCAR/Unidata. The user also
 * understands that UCAR/Unidata is not obligated to provide the user with
 * any support, consulting, training or assistance of any kind with regard
 * to the use, operation and performance of this software nor to provide
 * the user with any updates, revisions, new versions or "bug fixes."
 *
 * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
 */
package ucar.nc2;

import ucar.ma2.*;
import ucar.nc2.iosp.netcdf3.SPFactory;
import ucar.nc2.iosp.netcdf3.N3iosp;
import ucar.nc2.iosp.IOServiceProviderWriter;

import java.util.*;
import java.io.IOException;
import java.io.File;

/**
 * Create/Write netCDF-3 formatted files. 

* When a file is first created, it is in is "define mode", where the header objects (Dimensions, Attributes and Variables) * may be added, deleted and modified, but no data may be written. * Once create() is called, you can no longer modify the header, but you can now write data. * An existing file is opened in write mode.

* * If setRedefine(true) is called, the file goes into define mode, and header objects can be changed. * When setRedefine(false) is called, the new header is written, and the old file data is copied to the new file. * This can be quite costly. * * @author caron * @see NetcdfFile * @deprecated use NetcdfFileWriter */ public class NetcdfFileWriteable extends NetcdfFile { static private org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(NetcdfFileWriteable.class); static private Set valid = EnumSet.of(DataType.BYTE, DataType.CHAR, DataType.SHORT, DataType.INT, DataType.DOUBLE, DataType.FLOAT); /** * Open an existing Netcdf file for writing data. Fill mode is true. * Cannot add new objects, you can only read/write data to existing Variables. * * @param location name of existing file to open. * @return existing file that can be written to * @throws java.io.IOException on I/O error */ static public NetcdfFileWriteable openExisting(String location) throws IOException { return new NetcdfFileWriteable(location, true, true); } /** * Open an existing Netcdf file for writing data. * Cannot add new objects, you can only read/write data to existing Variables. * Setting fill = false is more efficient, use when you know you will write all data. * * @param location name of existing file to open. * @param fill if true, the data is first written with fill values. * @return existing file that can be written to * @throws IOException on I/O error */ static public NetcdfFileWriteable openExisting(String location, boolean fill) throws IOException { return new NetcdfFileWriteable(location, fill, true); } /** * Create a new Netcdf file, with fill mode true. * * @param location name of new file to open; if it exists, will overwrite it. * @return new file that can be written to * @throws IOException on I/O error */ static public NetcdfFileWriteable createNew(String location) throws IOException { return new NetcdfFileWriteable(location, true, false); } /** * Create a new Netcdf file, put it into define mode. Make calls to addXXX(), then * when all objects are added, call create(). You cannot read or write data until create() is called. * Setting fill = false is more efficient, use when you know you will write all data. * * @param location name of new file to open; if it exists, will overwrite it. * @param fill if true, the data is first written with fill values. * Leave false if you expect to write all data values, set to true if you want to be * sure that unwritten data values have the fill value in it. (default is false) * @return new file that can be written to * @throws IOException on I/O error */ static public NetcdfFileWriteable createNew(String location, boolean fill) throws IOException { return new NetcdfFileWriteable(location, fill, false); } //////////////////////////////////////////////////////////////////////////////// private IOServiceProviderWriter spiw; private IOServiceProviderWriter cached_spiw = null; // Hold the IOSP for deferred use in create() // modes private boolean defineMode; // state private boolean isNewFile; private boolean isLargeFile; private boolean fill; private int extraHeader; private long preallocateSize; /** * Open or create a new Netcdf file, put it into define mode to allow writing. * * @param location open a new file at this location * @param fill set fill mode * @param isExisting true if file already exists * @throws IOException on I/O error */ private NetcdfFileWriteable(String location, boolean fill, boolean isExisting) throws IOException { this(null, null, location, fill, isExisting); } /** * Open or create a new Netcdf file, put it into define mode to allow * writing, using the provided IOSP and RAF. * * @param iospw IO service provider to use, if null use standard * @param raf Random access file to use, may be null if iospw is * @param location open a new file at this location * @param fill set fill mode * @param isExisting true if file already exists * @throws IOException on I/O error */ protected NetcdfFileWriteable(IOServiceProviderWriter iospw, ucar.unidata.io.RandomAccessFile raf, String location, boolean fill, boolean isExisting) throws IOException { super(); this.location = location; this.fill = fill; if (isExisting) { if (iospw == null) { raf = new ucar.unidata.io.RandomAccessFile(location, "rw"); spi = SPFactory.getServiceProvider(); spiw = (IOServiceProviderWriter) spi; } else { spiw = iospw; spi = spiw; } spiw.open(raf, this, null); spiw.setFill( fill); } else { cached_spiw = iospw; // save for use later in create() defineMode = true; isNewFile = true; } } /** * Set the fill flag: call before calling create() or doing any data writing. * If true, the data is first written with fill values. * Default is fill = false. * Leave false if you expect to write all data values, set to true if you want to be * sure that unwritten data values have the fill value in it. * * @param fill set fill mode true or false */ public void setFill(boolean fill) { this.fill = fill; if (spiw != null) spiw.setFill( fill); } /** * Preallocate the file size, for efficiency. * Must be in define mode * Must call before create() to have any affect. * @param size if set to > 0, set length of file to this upon creation - this (usually) pre-allocates contiguous storage. */ public void setLength(long size) { if (!defineMode) throw new UnsupportedOperationException("not in define mode"); this.preallocateSize = size; } /** * Set if this should be a "large file" (64-bit offset) format. * Must be in define mode * @param isLargeFile true if large file */ public void setLargeFile(boolean isLargeFile) { if (!defineMode) throw new UnsupportedOperationException("not in define mode"); this.isLargeFile = isLargeFile; } /** * Set extra bytes to reserve in the header. * This can prevent rewriting the entire file on redefine. * Must be in define mode * @param extraHeaderBytes # bytes extra for the header */ public void setExtraHeaderBytes(int extraHeaderBytes) { if (!defineMode) throw new UnsupportedOperationException("not in define mode"); this.extraHeader = extraHeaderBytes; } /** * Is the file in define mode, which allows objects to be added and changed? * @return true if the file in define mode */ public boolean isDefineMode() { return defineMode; } //////////////////////////////////////////// //// use these calls in define mode /** * Add a Dimension to the file. Must be in define mode. * * @param dimName name of dimension * @param length size of dimension. * @return the created dimension */ public Dimension addDimension(String dimName, int length) { if (!defineMode) throw new UnsupportedOperationException("not in define mode"); if (length <= 0) throw new IllegalArgumentException("dimension length must be > 0 :"+length); if (!N3iosp.isValidNetcdfObjectName(dimName)) throw new IllegalArgumentException("illegal netCDF-3 dimension name: "+dimName); Dimension dim = new Dimension(dimName, length, true, false, false); super.addDimension(null, dim); return dim; } /** * Add a Dimension to the file. Must be in define mode. * * @param dimName name of dimension * @param length size of dimension. * @param isShared if dimension is shared * @param isUnlimited if dimension is unlimited * @param isVariableLength if dimension is variable length * @return the created dimension */ public Dimension addDimension(String dimName, int length, boolean isShared, boolean isUnlimited, boolean isVariableLength) { if (!defineMode) throw new UnsupportedOperationException("not in define mode"); if (!N3iosp.isValidNetcdfObjectName(dimName)) throw new IllegalArgumentException("illegal netCDF-3 dimension name "+dimName); Dimension dim = new Dimension(dimName, length, isShared, isUnlimited, isVariableLength); super.addDimension(null, dim); return dim; } /** * Add an unlimited Dimension to the file. Must be in define mode. * * @param dimName name of unlimited dimension * @return the created dimension */ public Dimension addUnlimitedDimension(String dimName) { return addDimension(dimName, 0, true, true, false); } /** * Rename a Dimension. Must be in define mode. * @param oldName existing dimension has this name * @param newName rename to this * @return renamed dimension, or null if not found */ public Dimension renameDimension(String oldName, String newName) { if (!defineMode) throw new UnsupportedOperationException("not in define mode"); Dimension dim = findDimension(oldName); if (null != dim) dim.setName(newName); return dim; } /** * Add a Global attribute to the file. Must be in define mode. * @param att the attribute. * @return the created attribute */ public Attribute addGlobalAttribute(Attribute att) { if (!defineMode) throw new UnsupportedOperationException("not in define mode"); if (!N3iosp.isValidNetcdfObjectName(att.getShortName())) { String attName = N3iosp.makeValidNetcdfObjectName(att.getShortName()); log.warn("illegal netCDF-3 attribute name= "+att.getShortName() + " change to "+ attName); att = new Attribute(attName, att.getValues()); } return super.addAttribute(null, att); } /** * Add a Global attribute of type String to the file. Must be in define mode. * * @param name name of attribute. * @param value value of atribute. * @return the created attribute */ public Attribute addGlobalAttribute(String name, String value) { return addGlobalAttribute( new Attribute(name, value)); } /** * Add a Global attribute of type Number to the file. Must be in define mode. * * @param name name of attribute. * @param value must be of type Float, Double, Integer, Short or Byte * @return the created attribute */ public Attribute addGlobalAttribute(String name, Number value) { return addGlobalAttribute( new Attribute(name, value)); } /** * Add a Global attribute of type Array to the file. Must be in define mode. * * @param name name of attribute. * @param values Array of values * @return the created attribute */ public Attribute addGlobalAttribute(String name, Array values) { return addGlobalAttribute( new Attribute(name, values)); } /** * Delete a global Attribute. Must be in define mode. * @param attName existing Attribute has this name * @return deleted Attribute, or null if not found */ public Attribute deleteGlobalAttribute(String attName) { if (!defineMode) throw new UnsupportedOperationException("not in define mode"); Attribute att = findGlobalAttribute(attName); if (null == att) return null; rootGroup.remove(att); return att; } /** * Rename a global Attribute. Must be in define mode. * @param oldName existing Attribute has this name * @param newName rename to this * @return renamed Attribute, or null if not found */ public Attribute renameGlobalAttribute(String oldName, String newName) { if (!defineMode) throw new UnsupportedOperationException("not in define mode"); Attribute att = findGlobalAttribute(oldName); if (null == att) return null; rootGroup.remove(att); att = new Attribute( newName, att.getValues()); rootGroup.addAttribute( att); return att; } /** * Add a variable to the file. Must be in define mode. * * @param varName name of Variable, must be unique with the file. * @param dataType type of underlying element * @param dims array of Dimensions for the variable, must already have been added. Use an array of length 0 * for a scalar variable. * @return the Variable that has been added */ public Variable addVariable(String varName, DataType dataType, Dimension[] dims) { ArrayList list = new ArrayList(); list.addAll(Arrays.asList(dims)); return addVariable(varName, dataType, list); } /** * Add a variable to the file. Must be in define mode. * * @param varName name of Variable, must be unique with the file. * @param dataType type of underlying element * @param dims names of Dimensions for the variable, blank seperated. * Must already have been added. Use an empty string for a scalar variable. * @return the Variable that has been added */ public Variable addVariable(String varName, DataType dataType, String dims) { // parse the list ArrayList list = new ArrayList(); StringTokenizer stoker = new StringTokenizer(dims); while (stoker.hasMoreTokens()) { String tok = stoker.nextToken(); Dimension d = rootGroup.findDimension(tok); if (null == d) throw new IllegalArgumentException("Cant find dimension " + tok); list.add(d); } return addVariable(varName, dataType, list); } /** * Add a variable to the file. Must be in define mode. * * @param shortName name of Variable, must be unique with the file. * @param dataType type of underlying element * @param dims list of Dimensions for the variable, must already have been added. Use a list of length 0 * for a scalar variable. * @return the Variable that has been added */ public Variable addVariable(String shortName, DataType dataType, List dims) { if (!defineMode) throw new UnsupportedOperationException("not in define mode"); if (!N3iosp.isValidNetcdfObjectName(shortName)) throw new IllegalArgumentException("illegal netCDF-3 variable name: "+shortName); if (!valid.contains(dataType)) throw new IllegalArgumentException("illegal dataType for netcdf-3 format: "+dataType); // check unlimited int count = 0; for (Dimension d : dims) { if (d.isUnlimited()) if (count != 0) throw new IllegalArgumentException("Unlimited dimension "+d+" must be first instead its ="+count); count++; } Variable v = new Variable(this, rootGroup, null, shortName); v.setDataType(dataType); v.setDimensions(dims); long size = v.getSize() * v.getElementSize(); if (size > N3iosp.MAX_VARSIZE) throw new IllegalArgumentException("Variable size in bytes "+size+" may not exceed "+ N3iosp.MAX_VARSIZE); super.addVariable(null, v); return v; } /** * Add a variable with DataType = String to the file. Must be in define mode. * The variable will be stored in the file as a CHAR variable. * A new dimension with name "varName_strlen" is automatically added, with length max_strlen. * * @param varName name of Variable, must be unique within the file. * @param dims list of Dimensions for the variable, must already have been added. Use a list of length 0 * for a scalar variable. Do not include the string length dimension. * @param max_strlen maximum string length. * @return the Variable that has been added */ public Variable addStringVariable(String varName, List dims, int max_strlen) { if (!defineMode) throw new UnsupportedOperationException("not in define mode"); if (!N3iosp.isValidNetcdfObjectName(varName)) throw new IllegalArgumentException("illegal netCDF-3 variable name: "+varName); Variable v = new Variable(this, rootGroup, null, varName); v.setDataType(DataType.CHAR); Dimension d = addDimension(varName + "_strlen", max_strlen); ArrayList sdims = new ArrayList(dims); sdims.add(d); v.setDimensions(sdims); super.addVariable(null, v); return v; } /** * Rename a Variable. Must be in define mode. * @param oldName existing Variable has this name * @param newName rename to this * @return renamed Variable, or null if not found */ public Variable renameVariable(String oldName, String newName) { if (!defineMode) throw new UnsupportedOperationException("not in define mode"); Variable v = findVariable(oldName); if (null != v) v.setName(newName); return v; } /** * Add an attribute to the named Variable. Must be in define mode. * * @param varName name of variable. must already have been added to the file. * @param att Attribute to add. */ public void addVariableAttribute(String varName, Attribute att) { if (!defineMode) throw new UnsupportedOperationException("not in define mode"); if (!N3iosp.isValidNetcdfObjectName(att.getShortName())) { String attName = N3iosp.makeValidNetcdfObjectName(att.getShortName()); log.warn("illegal netCDF-3 attribute name= "+att.getShortName() + " change to "+ attName); att = new Attribute(attName, att.getValues()); } Variable v = rootGroup.findVariable(varName); if (null == v) throw new IllegalArgumentException("addVariableAttribute variable name not found = <" + varName + ">"); v.addAttribute(att); } /** * Add an attribute of type String to the named Variable. Must be in define mode. * * @param varName name of variable. must already have been added to the file. * @param attName name of attribute. * @param value String value of atribute. */ public void addVariableAttribute(String varName, String attName, String value) { addVariableAttribute(varName, new Attribute(attName, value)); } /** * Add an attribute of type Number to the named Variable. Must be in define mode. * * @param varName name of variable. IllegalArgumentException if not valid name. * @param attName name of attribute. * @param value must be of type Float, Double, Integer, Short or Byte */ public void addVariableAttribute(String varName, String attName, Number value) { addVariableAttribute(varName, new Attribute(attName, value)); } /** * Add an attribute of type Array to the named Variable. Must be in define mode. * * @param varName name of variable. IllegalArgumentException if not valid name. * @param attName name of attribute. * @param value Array of valkues */ public void addVariableAttribute(String varName, String attName, Array value) { Attribute att = new Attribute(attName, value); addVariableAttribute(varName, att); } /** * Delete a variable Attribute. Must be in define mode. * @param varName existing Variable name * @param attName existing Attribute has this name * @return deleted Attribute, or null if not found */ public Attribute deleteVariableAttribute(String varName, String attName) { if (!defineMode) throw new UnsupportedOperationException("not in define mode"); Variable v = findVariable(varName); if (v == null) return null; Attribute att = v.findAttribute(attName); if (null == att) return null; v.remove(att); return att; } /** * Rename a variable Attribute. Must be in define mode. * @param varName existing Variable name * @param attName existing Attribute has this name * @param newName rename to this * @return renamed Attribute, or null if not found */ public Attribute renameVariableAttribute(String varName, String attName, String newName) { if (!defineMode) throw new UnsupportedOperationException("not in define mode"); Variable v = findVariable(varName); if (v == null) return null; Attribute att = v.findAttribute(attName); if (null == att) return null; v.remove(att); att = new Attribute( newName, att.getValues()); v.addAttribute( att); return att; } /** * Update the value of an existing attribute. Attribute is found by name, which must match exactly. * You cannot make an attribute longer, or change the number of values. * For strings: truncate if longer, zero fill if shorter. Strings are padded to 4 byte boundaries, ok to use padding if it exists. * For numerics: must have same number of values. * * @param v2 variable, or null for global attribute * @param att replace with this value * @throws IOException if I/O error */ public void updateAttribute(ucar.nc2.Variable v2, Attribute att) throws IOException { if (defineMode) throw new UnsupportedOperationException("in define mode"); spiw.updateAttribute(v2, att); } /** * After you have added all of the Dimensions, Variables, and Attributes, * call create() to actually create the file. You must be in define mode. * After this call, you are no longer in define mode. * @throws java.io.IOException if I/O error */ public void create() throws java.io.IOException { if (!defineMode) throw new UnsupportedOperationException("not in define mode"); if (cached_spiw == null) { spi = SPFactory.getServiceProvider(); spiw = (IOServiceProviderWriter) spi; } else { spiw = cached_spiw; spi = spiw; } spiw.setFill( fill); spiw.create(location, this, extraHeader, preallocateSize, isLargeFile); defineMode = false; } //////////////////////////////////////////// // redefine /** * Set the redefine mode. * Designed to emulate nc_redef (redefineMode = true) and * nc_enddef (redefineMode = false) * @param redefineMode start or end define mode * @return true if it had to rewrite the entire file, false if it wrote the header in place * @throws java.io.IOException on read/write error */ public boolean setRedefineMode(boolean redefineMode) throws IOException { if (redefineMode && !defineMode) { defineMode = true; } else if (!redefineMode && defineMode) { // we were in defineMode, and now we are ending. defineMode = false; finish(); // try to rewrite header, if it fails, then we have to rewrite entire file boolean ok = spiw.rewriteHeader( isLargeFile); // LOOK seems like we should be using isNewFile if (!ok) rewrite(); return !ok; } return false; } // rewrite entire file private void rewrite() throws IOException { // close existing file, rename and open as read-only spiw.flush(); spiw.close(); File prevFile = new File(location); File tmpFile = new File(location+".tmp"); if (tmpFile.exists()) tmpFile.delete(); if (!prevFile.renameTo(tmpFile)) { System.out.println(prevFile.getPath()+ " prevFile.exists "+prevFile.exists()+" canRead = "+ prevFile.canRead()); System.out.println(tmpFile.getPath()+" tmpFile.exists "+tmpFile.exists()+" canWrite "+ tmpFile.canWrite()); throw new RuntimeException("Cant rename "+prevFile.getAbsolutePath()+" to "+ tmpFile.getAbsolutePath()); } NetcdfFile oldFile = NetcdfFile.open(tmpFile.getPath()); // use record dimension if it has one Structure recordVar = null; if (oldFile.hasUnlimitedDimension()) { oldFile.sendIospMessage(NetcdfFile.IOSP_MESSAGE_ADD_RECORD_STRUCTURE); recordVar = (Structure) oldFile.findVariable("record"); /* if (recordVar != null) { Boolean result = (Boolean) spiw.sendIospMessage(NetcdfFile.IOSP_MESSAGE_ADD_RECORD_STRUCTURE); if (!result) recordVar = null; } */ } // create new file with current set of objects spiw.create(location, this, extraHeader, preallocateSize, isLargeFile); spiw.setFill( fill); //isClosed = false; // wait till header is written before adding the record variable to the file if (recordVar != null) { Boolean result = (Boolean) spiw.sendIospMessage(NetcdfFile.IOSP_MESSAGE_ADD_RECORD_STRUCTURE); if (!result) recordVar = null; } // copy old file to new List oldList = new ArrayList(getVariables().size()); for (Variable v : getVariables()) { Variable oldVar = oldFile.findVariable(v.getFullNameEscaped()); if (oldVar != null) oldList.add(oldVar); } FileWriter.copyVarData(this, oldList, recordVar, null); flush(); // delete old oldFile.close(); if (!tmpFile.delete()) throw new RuntimeException("Cant delete "+location); } //////////////////////////////////////////// //// use these calls to write data to the file /** * Write data to the named variable, origin assumed to be 0. Must not be in define mode. * * @param fullNameEsc name of variable. IllegalArgumentException if variable name does not exist. * @param values write this array; must be same type and rank as Variable * @throws IOException if I/O error * @throws ucar.ma2.InvalidRangeException if values Array has illegal shape */ public void write(String fullNameEsc, Array values) throws java.io.IOException, InvalidRangeException { write(fullNameEsc, new int[values.getRank()], values); } /** * Write data to the named variable. Must not be in define mode. * * @param fullNameEsc full, escaped name of variable. IllegalArgumentException if variable name does not exist. * @param origin offset within the variable to start writing. * @param values write this array; must be same type and rank as Variable * @throws IOException if I/O error * @throws ucar.ma2.InvalidRangeException if values Array has illegal shape */ public void write(String fullNameEsc, int[] origin, Array values) throws java.io.IOException, InvalidRangeException { if (defineMode) throw new UnsupportedOperationException("in define mode"); ucar.nc2.Variable v2 = findVariable(fullNameEsc); if (v2 == null) throw new IllegalArgumentException("NetcdfFileWriteable.write illegal variable name = " + fullNameEsc); spiw.writeData(v2, new Section(origin, values.getShape()), values); v2.invalidateCache(); } /** * Write String data to a CHAR variable, origin assumed to be 0. Must not be in define mode. * * @param varName name of variable, must be of type CHAR. * @param values write this array; must be ArrayObject of String * @throws IOException if I/O error * @throws ucar.ma2.InvalidRangeException if values Array has illegal shape */ public void writeStringData(String varName, Array values) throws java.io.IOException, InvalidRangeException { writeStringData(varName, new int[values.getRank()], values); } /** * Write String data to a CHAR variable. Must not be in define mode. * * @param fullNameEsc name of variable, must be of type CHAR. * @param origin offset to start writing, ignore the strlen dimension. * @param values write this array; must be ArrayObject of String * @throws IOException if I/O error * @throws ucar.ma2.InvalidRangeException if values Array has illegal shape */ public void writeStringData(String fullNameEsc, int[] origin, Array values) throws java.io.IOException, InvalidRangeException { if (values.getElementType() != String.class) throw new IllegalArgumentException("Must be ArrayObject of String "); ucar.nc2.Variable v2 = findVariable(fullNameEsc); if (v2 == null) throw new IllegalArgumentException("illegal variable name = " + fullNameEsc); if (v2.getDataType() != DataType.CHAR) throw new IllegalArgumentException("variable " + fullNameEsc + " is not type CHAR"); int rank = v2.getRank(); int strlen = v2.getShape(rank-1); // turn it into an ArrayChar ArrayChar cvalues = ArrayChar.makeFromStringArray((ArrayObject) values, strlen); int[] corigin = new int[rank]; System.arraycopy(origin, 0, corigin, 0, rank - 1); write(fullNameEsc, corigin, cvalues); } /** * Flush anything written to disk. * @throws IOException if I/O error */ public void flush() throws java.io.IOException { spiw.flush(); } /** * close the file. * @throws IOException if I/O error */ @Override public synchronized void close() throws java.io.IOException { if (spiw != null) { flush(); spiw.close(); spiw = null; } spi = null; } public String getFileTypeId() { return "netCDF"; } public String getFileTypeDescription() { return "netCDF classic format - writer"; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // deprecated /** * Create a new Netcdf file, put it into define mode. * * @param location open a new file at this location * @param fill set fill mode * @deprecated use createNew(String filename, boolean fill) */ public NetcdfFileWriteable(String location, boolean fill) { super(); this.location = location; this.fill = fill; defineMode = true; } /** * Open a new Netcdf file, put it into define mode. * * @deprecated use createNew(String filename, boolean fill) */ public NetcdfFileWriteable() { super(); defineMode = true; } /** * Open an existing Netcdf file for writing data. * * @param location open an existing file at this location * @deprecated use openExisting(String filename, boolean fill) * @throws java.io.IOException on read error */ public NetcdfFileWriteable(String location) throws IOException { super(); this.location = location; ucar.unidata.io.RandomAccessFile raf = new ucar.unidata.io.RandomAccessFile(location, "rw"); spi = SPFactory.getServiceProvider(); spiw = (IOServiceProviderWriter) spi; spiw.open(raf, this, null); } /** * Set the filename of a new file to be created: call before calling create(). * @param filename name of new file to create. * @deprecated use NetcdfFileWriteable.createNew(String filename); */ public void setName(String filename) { this.location = filename; } /** * Add a variable to the file. Must be in define mode. * * @param varName name of Variable, must be unique with the file. * @param componentType type of underlying element: String, double or Double, etc. * @param dims array of Dimensions for the variable, must already have been added. * @deprecated use addVariable(String varName, DataType dataType, ArrayList dims); * @return the Varible added */ public Variable addVariable(String varName, Class componentType, Dimension[] dims) { List list = new ArrayList(); list.addAll(Arrays.asList(dims)); return addVariable(varName, DataType.getType(componentType), list); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy