简体   繁体   中英

Deleting zip file after accessing with apache commons vfs2 in Java

I'm trying to experiment with apache commons vfs2 to read content of a zip file as if it is just another directory. The zip files will ultimately hold all kinds of files (perhaps even a small database).

For illustration purposes, I have created some zip files containing a file called project.json which is json for a project with a name and a description. When I get the zip file, I want to read the json file to get the project definition information, etc. from within.

This all works great. Now, I want my users to be able to delete these files from within the application. This is where things go south on me.

I think I closed all of the input streams and such, but there appears to be a lock on the file from within the application that will not allow me to delete it.

  • If I create the zip file within the context of my application, I am allowed to delete it.
  • If I read it from the file system and DO NOT access it using vfs2, I AM allowed to delete it.
  • If I read it from the file system and access it using vfs2, I am NOT allowed to delete it.

Here's a simple json string if you want to create your own zip file to try it.

{"project": {"name": "ProjectX", "description": "X is a project."}}

Copy that to a file called project.json, and save it. Then, zip it into a zip file in the root directory of the Java project.

The following example illustrates my dilemma:

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.vfs2.FileContent;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemManager;
import org.apache.commons.vfs2.VFS;
import org.json.JSONObject;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.stage.Stage;

public class FileLockExample extends Application {

    @Override
    public void start(Stage arg0) throws Exception {
        ObservableList<File> files = retrieveFiles();
        deleteFiles(files);
        Platform.exit();
    }

    public static void main(String[] args) {
        Application.launch(args);
    }

    public ObservableList<File> retrieveFiles() {
        File[] files = new File(".").listFiles(new FilenameFilter() { 
            @Override 
            public boolean accept(File dir, String name) { 
                return name.endsWith(".zip");
            }
        });
        for (File file : files) {
            try {
                FileSystemManager fsManager = VFS.getManager();
                FileObject zipFile = fsManager.resolveFile("zip:" + file.toURI());
                FileObject projectJson = fsManager.resolveFile(zipFile, "project.json");
                FileContent content = projectJson.getContent();

                InputStream in = content.getInputStream();
                byte[] buffer = new byte[1024];
                StringBuilder sb = new StringBuilder();
                int len;
                while ((len = in.read(buffer)) > 0) {
                    sb.append(new String(buffer, 0, len));
                }
                in.close();
                String json = sb.toString();

                JSONObject obj = new JSONObject(json);
                String name = obj.getJSONObject("project").getString("name");
                String description = obj.getJSONObject("project").getString("description");
                System.out.println("Found project : " + name + "(" + description + ")");
                content.close();
                projectJson.close();
                zipFile.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return FXCollections.observableArrayList(files);
    }

    public void deleteFiles(ObservableList<File> files) {
        for (File file : files) {
            System.out.println("Deleting " + file.getName());
            file.deleteOnExit();
        }
    }
}

In light of the fact that no one seemed interested in my question, it caused me to reflect on the use of Apache Commons VFS in this case. I decided to explore other options, and was able to accomplish my short-term goal by using the java.nio API. Now, on to the longer-term goal of attempting to store other types of files in the zip file, and access them in a random fashion.

In case anyone cares, here is my sample code to read from and delete zip files from the file system without having to resort to InputStream and OutputStream .

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.*;
import java.nio.file.spi.FileSystemProvider;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.json.JSONObject;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.stage.Stage;

public class FileLockExample extends Application {

    @Override
    public void start(Stage arg0) throws Exception {
        ObservableList<File> files = retrieveFiles();
        deleteFiles(files);
        Platform.exit();
    }

    public static void main(String[] args) {
        Application.launch(args);
    }

    public ObservableList<File> retrieveFiles() {
        File[] files = new File(".").listFiles(new FilenameFilter() { 
            @Override 
            public boolean accept(File dir, String name) { 
                return name.endsWith(".zip");
            }
        });
        for (File file : files) {
            try {
                Map<String, Object> env = new HashMap<>();
                FileSystemProvider provider = getZipFSProvider();
                URI uri = new URI("jar:" + file.toURI());
                FileSystem zipfs = provider.newFileSystem(uri, env);
                List<String> jsonList = Files.readAllLines(zipfs.getPath("/project.json"));
                StringBuilder sb = new StringBuilder();
                for (String string : jsonList) {
                    sb.append(string);
                }
                String json = sb.toString();
                JSONObject obj = new JSONObject(json);
                String name = obj.getJSONObject("project").getString("name");
                String description = obj.getJSONObject("project").getString("description");
                System.out.println("Found project : " + name + " (" + description + ")");
            } catch (URISyntaxException use) {
                use.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return FXCollections.observableArrayList(files);
    }

    public void deleteFiles(ObservableList<File> files) {
        for (File file : files) {
            System.out.println("Deleting " + file.getName());
            file.deleteOnExit();
        }
    }

    private static FileSystemProvider getZipFSProvider() {
        for (FileSystemProvider provider : FileSystemProvider.installedProviders()) {
            if ("jar".equals(provider.getScheme()))
                return provider;
        }
        return null;
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM