📄 shpfiles.java
字号:
/**
*
*/
package org.geotools.data.shapefile;
import static org.geotools.data.shapefile.ShpFileType.SHP;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.FilterInputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.geotools.data.DataUtilities;
/**
* The collection of all the files that are the shapefile and its metadata and
* indices.
*
* <p>
* This class has methods for performing actions on the files. Currently mainly
* for obtaining read and write channels and streams. But in the future a move
* method may be introduced.
* </p>
*
* <p>
* Note: The method that require locks (such as getInputStream()) will
* automatically acquire locks and the javadocs should document how to release
* the lock. Therefore the methods {@link #acquireRead(ShpFileType, FileReader)}
* and {@link #acquireWrite(ShpFileType, FileWriter)}svn
* </p>
*
* @author jesse
*/
public class ShpFiles {
/**
* The urls for each type of file that is associated with the shapefile. The
* key is the type of file
*/
private final Map<ShpFileType, URL> urls = new HashMap<ShpFileType, URL>();
private final Lock readWriteLock = new ReentrantLock();
private final Collection<ShpFilesLocker> lockers = new LinkedList<ShpFilesLocker>();
/**
* Searches for all the files and adds then to the map of files.
*
* @param fileName
* the filename or url of any one of the shapefile files
* @throws MalformedURLException
* if it isn't possible to create a URL from string. It will
* be used to create a file and create a URL from that if
* both fail this exception is thrown
*/
public ShpFiles(String fileName) throws MalformedURLException {
try {
URL url = new URL(fileName);
init(url);
} catch (MalformedURLException e) {
init(new File(fileName).toURI().toURL());
}
}
/**
* Searches for all the files and adds then to the map of files.
*
* @param file
* any one of the shapefile files
*
* @throws FileNotFoundException
* if the shapefile associated with file is not found
*/
public ShpFiles(File file) throws MalformedURLException {
init(file.toURI().toURL());
}
/**
* Searches for all the files and adds then to the map of files.
*
* @param file
* any one of the shapefile files
*
*/
public ShpFiles(URL url) throws IllegalArgumentException {
init(url);
}
private void init(URL url) {
String base = baseName(url);
if (base == null) {
throw new IllegalArgumentException(
url.getPath()
+ " is not one of the files types that is known to be associated with a shapefile");
}
String urlString = url.toExternalForm();
char lastChar = urlString.charAt(urlString.length()-1);
boolean upperCase = Character.isUpperCase(lastChar);
for (ShpFileType type : ShpFileType.values()) {
String extensionWithPeriod = type.extensionWithPeriod;
if( upperCase ){
extensionWithPeriod = extensionWithPeriod.toUpperCase();
}else{
extensionWithPeriod = extensionWithPeriod.toLowerCase();
}
URL newURL;
String string = base + extensionWithPeriod;
try {
newURL = new URL(url, string);
} catch (MalformedURLException e) {
// shouldn't happen because the starting url was constructable
throw new RuntimeException(e);
}
urls.put(type, newURL);
}
// if the files are local check each file to see if it exists
// if not then search for a file of the same name but try all combinations of the
// different cases that the extension can be made up of.
// IE Shp, SHP, Shp, ShP etc...
if( isLocal() ){
Set<Entry<ShpFileType, URL>> entries = urls.entrySet();
Map<ShpFileType, URL> toUpdate = new HashMap<ShpFileType, URL>();
for (Entry<ShpFileType, URL> entry : entries) {
if( !exists(entry.getKey()) ){
url = findExistingFile(entry.getKey(), entry.getValue());
if( url!=null ){
toUpdate.put(entry.getKey(), url);
}
}
}
urls.putAll(toUpdate);
}
}
private URL findExistingFile(ShpFileType shpFileType, URL value) {
final File file = DataUtilities.urlToFile(value);
File directory = file.getParentFile();
if( directory==null ){
// doesn't exist
return null;
}
File[] files = directory.listFiles(new FilenameFilter(){
public boolean accept(File dir, String name) {
return file.getName().equalsIgnoreCase(name);
}
});
if( files.length>0 ){
try {
return files[0].toURI().toURL();
} catch (MalformedURLException e) {
ShapefileDataStoreFactory.LOGGER.log(Level.SEVERE, "", e);
}
}
return null;
}
/**
* This verifies that this class has been closed correctly (nothing locking)
*/
@Override
protected void finalize() throws Throwable {
super.finalize();
dispose();
}
void dispose() {
if (numberOfLocks() != 0) {
logCurrentLockers(Level.SEVERE);
lockers.clear(); // so as not to get this log again.
}
}
/**
* Writes to the log all the lockers and when they were constructed.
*
* @param logLevel
* the level at which to log.
*/
public void logCurrentLockers(Level logLevel) {
for (ShpFilesLocker locker : lockers) {
ShapefileDataStoreFactory.LOGGER
.log(
logLevel,
"The following locker still has a lock
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -