看了一下

public interface FeatureIterator<F extends Feature> extends Closeable

作者提供的方法

/**
 * Streaming access to features, required to {@link #close()} after use.
 *
 * <p>FeatureIterator is a drop in replacement for Iterator<Feature> supporting a close method.
 *
 * <p>Sample use:
 *
 * <pre> FeatureIterator<SimpleFeature> i = featureCollection.features()
 * try {
 *    while( i.hasNext() ){
 *        SimpleFeature feature = i.next();
 *    }
 * }
 * finally {
 *    i.close();
 * }
 * </pre>
 *
 * @author Ian Schneider
 */

自己写的ShapeFileReader 在遍历数据的时候出现java.nio.BufferUnderflowException: null异常,完整的异常堆栈信息如下:

java.nio.BufferUnderflowException: null

at java.base/java.nio.DirectDoubleBufferU.get(DirectDoubleBufferU.java:295)

at org.geotools.data.shapefile.shp.PolygonHandler.readCoordinates(PolygonHandler.java:304)

at org.geotools.data.shapefile.shp.PolygonHandler.read(PolygonHandler.java:143)

at org.geotools.data.shapefile.shp.ShapefileReader$Record.shape(ShapefileReader.java:113)

at org.geotools.data.shapefile.ShapefileFeatureReader.getGeometry(ShapefileFeatureReader.java:238)

at org.geotools.data.shapefile.ShapefileFeatureReader.hasNext(ShapefileFeatureReader.java:181)

at org.geotools.data.store.ContentFeatureCollection$WrappingFeatureIterator.hasNext(ContentFeatureCollection.java:138)

查看at java.base/java.nio.DirectDoubleBufferU.get(DirectDoubleBufferU.java:295)的代码,如下:

public DoubleBuffer get(double[] dst, int offset, int length) {
    if ((long)length << 3 > 6L) {
        checkBounds(offset, length, dst.length);
        int pos = this.position();
        int lim = this.limit();

        assert pos <= lim;

        int rem = pos <= lim ? lim - pos : 0;
        if (length > rem) {
            throw new BufferUnderflowException();
        }

        long dstOffset = ARRAY_BASE_OFFSET + ((long)offset << 3);

        try {
            if (this.order() != ByteOrder.nativeOrder()) {
                UNSAFE.copySwapMemory((Object)null, this.ix(pos), dst, dstOffset, (long)length << 3, 8L);
            } else {
                UNSAFE.copyMemory((Object)null, this.ix(pos), dst, dstOffset, (long)length << 3);
            }
        } finally {
            Reference.reachabilityFence(this);
        }

        this.position(pos + length);
    } else {
        super.get(dst, offset, length);
    }

    return this;
}

具体是下面这个判断条件

if (length > rem) {
    throw new BufferUnderflowException();
}

说明是记录长度大于内存长度

`BufferUnderflowException`是一种运行时异常,通常发生在缓冲区数据不足的情况下。当试图从一个空的或已经读取完数据的缓冲区中读取数据时,就会抛出这个异常。

在Java中,`BufferUnderflowException`是`java.nio.BufferUnderflowException`类,它表示尝试从缓冲区中读取数据时没有足够的可用数据。

要处理`BufferUnderflowException`,可以采取以下措施:

1. 检查缓冲区是否为空或者是否已经读取完数据。如果是这种情况,需要先向缓冲区中添加足够的数据,然后再进行读取操作。

2. 如果缓冲区的大小不足以满足需求,可以考虑增加缓冲区的大小。这可以通过调整缓冲区的容量来实现。

3. 如果缓冲区的数据是从外部输入流中读取的,可以尝试使用循环来不断读取数据,直到有足够的数据可供使用。

4. 另外,还可以考虑捕获`BufferUnderflowException`异常并进行适当的错误处理,例如记录日志、显示错误信息等。

换其他shp文件读取正常,说明不是所有的shp文件读取会出现BufferUnderflowException,只能说是有出现BufferUnderflowException的shp文件有问题。