⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbasefileheader.java

📁 shape file read and write
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
                tempLength += tempFieldDescriptors[j].fieldLength;
                // only increment j on non-matching fields
                j++;
            } else {
                retCol = i;
            }
        }

        // set the new fields.
        fields = tempFieldDescriptors;
        headerLength = 33 + 32 * fields.length;
        recordLength = tempLength;

        return retCol;
    }

    // Retrieve the length of the field at the given index
    /**
     * Returns the field length in bytes.
     * 
     * @param inIndex
     *                The field index.
     * @return The length in bytes.
     */
    public int getFieldLength(int inIndex) {
        return fields[inIndex].fieldLength;
    }

    // Retrieve the location of the decimal point within the field.
    /**
     * Get the decimal count of this field.
     * 
     * @param inIndex
     *                The field index.
     * @return The decimal count.
     */
    public int getFieldDecimalCount(int inIndex) {
        return fields[inIndex].decimalCount;
    }

    // Retrieve the Name of the field at the given index
    /**
     * Get the field name.
     * 
     * @param inIndex
     *                The field index.
     * @return The name of the field.
     */
    public String getFieldName(int inIndex) {
        return fields[inIndex].fieldName;
    }

    // Retrieve the type of field at the given index
    /**
     * Get the character class of the field.
     * 
     * @param inIndex
     *                The field index.
     * @return The dbase character representing this field.
     */
    public char getFieldType(int inIndex) {
        return fields[inIndex].fieldType;
    }

    /**
     * Get the date this file was last updated.
     * 
     * @return The Date last modified.
     */
    public Date getLastUpdateDate() {
        return date;
    }

    /**
     * Return the number of fields in the records.
     * 
     * @return The number of fields in this table.
     */
    public int getNumFields() {
        return fields.length;
    }

    /**
     * Return the number of records in the file
     * 
     * @return The number of records in this table.
     */
    public int getNumRecords() {
        return recordCnt;
    }

    /**
     * Get the length of the records in bytes.
     * 
     * @return The number of bytes per record.
     */
    public int getRecordLength() {
        return recordLength;
    }

    /**
     * Get the length of the header
     * 
     * @return The length of the header in bytes.
     */
    public int getHeaderLength() {
        return headerLength;
    }

    /**
     * Read the header data from the DBF file.
     * 
     * @param channel
     *                A readable byte channel. If you have an InputStream you
     *                need to use, you can call
     *                java.nio.Channels.getChannel(InputStream in).
     * @throws IOException
     *                 If errors occur while reading.
     */
    public void readHeader(ReadableByteChannel channel) throws IOException {
        // we'll read in chunks of 1K
        ByteBuffer in = ByteBuffer.allocateDirect(1024);
        // do this or GO CRAZY
        // ByteBuffers come preset to BIG_ENDIAN !
        in.order(ByteOrder.LITTLE_ENDIAN);

        // only want to read first 10 bytes...
        in.limit(10);

        read(in, channel);
        in.position(0);

        // type of file.
        byte magic = in.get();
        if (magic != MAGIC) {
            throw new IOException("Unsupported DBF file Type "
                    + Integer.toHexString(magic));
        }

        // parse the update date information.
        int tempUpdateYear = in.get();
        int tempUpdateMonth = in.get();
        int tempUpdateDay = in.get();
        // ouch Y2K uncompliant
        if (tempUpdateYear > 90) {
            tempUpdateYear = tempUpdateYear + 1900;
        } else {
            tempUpdateYear = tempUpdateYear + 2000;
        }
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, tempUpdateYear);
        c.set(Calendar.MONTH, tempUpdateMonth - 1);
        c.set(Calendar.DATE, tempUpdateDay);
        date = c.getTime();

        // read the number of records.
        recordCnt = in.getInt();

        // read the length of the header structure.
        // ahhh.. unsigned little-endian shorts
        // mask out the byte and or it with shifted 2nd byte
        headerLength = (in.get() & 0xff) | ((in.get() & 0xff) << 8);

        // if the header is bigger than our 1K, reallocate
        if (headerLength > in.capacity()) {
            NIOUtilities.clean(in);
            in = ByteBuffer.allocateDirect(headerLength - 10);
        }
        in.limit(headerLength - 10);
        in.position(0);
        read(in, channel);
        in.position(0);

        // read the length of a record
        // ahhh.. unsigned little-endian shorts
        recordLength = (in.get() & 0xff) | ((in.get() & 0xff) << 8);

        // skip / skip thesreserved bytes in the header.
        in.position(in.position() + 20);

        // calculate the number of Fields in the header
        fieldCnt = (headerLength - FILE_DESCRIPTOR_SIZE - 1)
                / FILE_DESCRIPTOR_SIZE;

        // read all of the header records
        List lfields = new ArrayList();
        for (int i = 0; i < fieldCnt; i++) {
            DbaseField field = new DbaseField();

            // read the field name
            byte[] buffer = new byte[11];
            in.get(buffer);
            String name = new String(buffer);
            int nullPoint = name.indexOf(0);
            if (nullPoint != -1) {
                name = name.substring(0, nullPoint);
            }
            field.fieldName = name.trim();

            // read the field type
            field.fieldType = (char) in.get();

            // read the field data address, offset from the start of the record.
            field.fieldDataAddress = in.getInt();

            // read the field length in bytes
            int length = (int) in.get();
            if (length < 0) {
                length = length + 256;
            }
            field.fieldLength = length;

            if (length > largestFieldSize) {
                largestFieldSize = length;
            }

            // read the field decimal count in bytes
            field.decimalCount = (int) in.get();

            // rreservedvededved bytes.
            // in.skipBytes(14);
            in.position(in.position() + 14);

            // some broken shapefiles have 0-length attributes. The reference
            // implementation
            // (ArcExplorer 2.0, built with MapObjects) just ignores them.
            if (field.fieldLength > 0) {
                lfields.add(field);
            }
        }

        // Last byte is a marker for the end of the field definitions.
        // in.skipBytes(1);
        in.position(in.position() + 1);

        NIOUtilities.clean(in);

        fields = new DbaseField[lfields.size()];
        fields = (DbaseField[]) lfields.toArray(fields);
    }

    /**
     * Get the largest field size of this table.
     * 
     * @return The largt field size iiin bytes.
     */
    public int getLargestFieldSize() {
        return largestFieldSize;
    }

    /**
     * Set the number of records in the file
     * 
     * @param inNumRecords
     *                The number of records.
     */
    public void setNumRecords(int inNumRecords) {
        recordCnt = inNumRecords;
    }

    /**
     * Write the header data to the DBF file.
     * 
     * @param out
     *                A channel to write to. If you have an OutputStream you can
     *                obtain the correct channel by using
     *                java.nio.Channels.newChannel(OutputStream out).
     * @throws IOException
     *                 If errors occur.
     */
    public void writeHeader(WritableByteChannel out) throws IOException {
        // take care of the annoying case where no records have been added...
        if (headerLength == -1) {
            headerLength = MINIMUM_HEADER;
        }
        ByteBuffer buffer = ByteBuffer.allocateDirect(headerLength);
        buffer.order(ByteOrder.LITTLE_ENDIAN);

        // write the output file type.
        buffer.put((byte) MAGIC);

        // write the date stuff
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        buffer.put((byte) (c.get(Calendar.YEAR) % 100));
        buffer.put((byte) (c.get(Calendar.MONTH) + 1));
        buffer.put((byte) (c.get(Calendar.DAY_OF_MONTH)));

        // write the number of records in the datafile.
        buffer.putInt(recordCnt);

        // write the length of the header structure.
        buffer.putShort((short) headerLength);

        // write the length of a record
        buffer.putShort((short) recordLength);

        // // write the reserved bytes in the header
        // for (int i=0; i<20; i++) out.writeByteLE(0);
        buffer.position(buffer.position() + 20);

        // write all of the header records
        int tempOffset = 0;
        for (int i = 0; i < fields.length; i++) {

            // write the field name
            for (int j = 0; j < 11; j++) {
                if (fields[i].fieldName.length() > j) {
                    buffer.put((byte) fields[i].fieldName.charAt(j));
                } else {
                    buffer.put((byte) 0);
                }
            }

            // write the field type
            buffer.put((byte) fields[i].fieldType);
            // // write the field data address, offset from the start of the
            // record.
            buffer.putInt(tempOffset);
            tempOffset += fields[i].fieldLength;

            // write the length of the field.
            buffer.put((byte) fields[i].fieldLength);

            // write the decimal count.
            buffer.put((byte) fields[i].decimalCount);

            // write the reserved bytes.
            // for (in j=0; jj<14; j++) out.writeByteLE(0);
            buffer.position(buffer.position() + 14);
        }

        // write the end of the field definitions marker
        buffer.put((byte) 0x0D);

        buffer.position(0);

        int r = buffer.remaining();
        while ((r -= out.write(buffer)) > 0) {
            ; // do nothing
        }

        NIOUtilities.clean(buffer);
    }

    /**
     * Get a simple representation of this header.
     * 
     * @return A String representing the state of the header.
     */
    public String toString() {
        StringBuffer fs = new StringBuffer();
        for (int i = 0, ii = fields.length; i < ii; i++) {
            DbaseField f = fields[i];
            fs.append(f.fieldName + " " + f.fieldType + " " + f.fieldLength
                    + " " + f.decimalCount + " " + f.fieldDataAddress + "\n");
        }

        return "DB3 Header\n" + "Date : " + date + "\n" + "Records : "
                + recordCnt + "\n" + "Fields : " + fieldCnt + "\n" + fs;

    }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -