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

📄 storagefile.java

📁 shape file read and write
💻 JAVA
字号:
/**
 * 
 */
package org.geotools.data.shapefile;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URL;
import java.nio.channels.FileChannel;
import java.util.Arrays;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.logging.Level;

import org.geotools.data.DataUtilities;

/**
 * Encapsulates the idea of a file for writing data to and then later updating the original.
 * 
 * @author jesse
 */
public final class StorageFile implements Comparable<StorageFile>, FileWriter {
    private final ShpFiles shpFiles;
    private final File tempFile;
    private final ShpFileType type;

    public StorageFile( ShpFiles shpFiles, File tempFile, ShpFileType type ) {
        this.shpFiles = shpFiles;
        this.tempFile = tempFile;
        this.type = type;
    }

    /**
     * Returns the storage file
     * 
     * @return the storage file
     */
    public File getFile() {
        return tempFile;
    }

    public FileChannel getWriteChannel() throws IOException {
        return new RandomAccessFile(tempFile, "rw").getChannel();
    }

    /**
     * Replaces the file that the temporary file is acting as a transactional type cache for. Acts
     * similar to a commit.
     * 
     * @see #replaceOriginals(StorageFile...)
     * @throws IOException
     */
    public void replaceOriginal() throws IOException {
        replaceOriginals(this);
    }

    /**
     * Takes a collection of StorageFiles and performs the replace functionality described in
     * {@link #replaceOriginal()}. However, all files that are part of the same {@link ShpFiles}
     * are done within a lock so all of the updates for all the Files of a Shapefile can be updated
     * within a single lock.
     * 
     * @param storageFiles files to execute the replace functionality.
     * @throws IOException
     */
    public static void replaceOriginals( StorageFile... storageFiles ) throws IOException {
        SortedSet<StorageFile> files = new TreeSet<StorageFile>(Arrays.asList(storageFiles));

        ShpFiles currentShpFiles = null;
        URL shpURL = null;
        StorageFile locker = null;
        for( StorageFile storageFile : files ) {
            if (currentShpFiles != storageFile.shpFiles) {
                // there's a new set of files so unlock old and lock new.
                unlock(currentShpFiles, shpURL, locker);
                locker = storageFile;
                currentShpFiles = storageFile.shpFiles;
                shpURL = currentShpFiles.acquireWrite(ShpFileType.SHP, storageFile);
            }

            File storage = storageFile.getFile();

            URL url = storageFile.getSrcURLForWrite();
            try {
                File dest = DataUtilities.urlToFile(url);

                if (storage.equals(dest))
                    return;

                if (dest.exists()) {
                    if (!dest.delete()){
                        ShapefileDataStoreFactory.LOGGER.severe("Unable to delete the file: "+dest+" when attempting to replace with temporary copy.");
                        if( storageFile.shpFiles.numberOfLocks()>0 ){
                            ShapefileDataStoreFactory.LOGGER.severe("The problem is almost certainly caused by the fact that there are still locks being held on the shapefiles.  Probably a reader or writer was left unclosed");
                            storageFile.shpFiles.logCurrentLockers(Level.SEVERE);
                        }
//                        throw new IOException("Unable to delete original file: " + url);
                    }
                }

                if (storage.exists() && !storage.renameTo(dest)) {
                    ShapefileDataStoreFactory.LOGGER.finer("Unable to rename temporary file to the file: "+dest+" when attempting to replace with temporary copy");
                    
                    copyFile(storage, url, dest);
                    if (!storage.delete()) {
                        storage.deleteOnExit();
                    }
                }
            } finally {
                storageFile.unlockWriteURL(url);

                if (storage.exists()) {
                    storage.delete();
                }
            }
        }
        unlock(currentShpFiles, shpURL, locker);

    }

    private static void copyFile( File storage, URL url, File dest ) throws FileNotFoundException,
            IOException {
        FileChannel in = null;
        FileChannel out = null;
        try {
            in = new FileInputStream(storage).getChannel();
            out = new FileOutputStream(dest).getChannel();

            // magic number for Windows, 64Mb - 32Kb)
            int maxCount = (64 * 1024 * 1024) - (32 * 1024);
            long size = in.size();
            long position = 0;
            while( position < size ) {
                position += in.transferTo(position, maxCount, out);
            }
        } finally {
            if (in != null) {
                in.close();
            }
            if (out != null) {
                out.close();
            }
        }
    }

    private URL getSrcURLForWrite() {
        return shpFiles.acquireWrite(type, this);
    }

    private void unlockWriteURL( URL url ) {
        shpFiles.unlockWrite(url, this);
    }

    private static void unlock( ShpFiles currentShpFiles, URL shpURL, StorageFile locker ) {
        // no lock to be unlocked
        if (currentShpFiles == null) {
            return;
        }

        currentShpFiles.unlockWrite(shpURL, locker);
    }

    /**
     * Just groups together files that have the same ShpFiles instance
     */
    public int compareTo( StorageFile o ) {
        if (this == o) {
            return 0;
        }
        if (!shpFiles.equals(o.shpFiles)) {
            return 1;
        }
        return -1;
    }

    @Override
    public String toString() {
        return id();
    }

    public String id() {
        return getClass().getSimpleName() + ": " + tempFile.getName();
    }

}

⌨️ 快捷键说明

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