在Java

时间:2016-04-16 05:23:00

标签: java json javafx zip apache-commons-vfs

我试图尝试使用apache commons vfs2来读取zip文件的内容,就像它只是另一个目录一样。 zip文件最终将包含各种文件(甚至可能是一个小型数据库)。

为了便于说明,我创建了一些包含名为project.json的文件的zip文件,该文件是带有名称和描述的项目的json。当我获得zip文件时,我想读取json文件以从内部获取项目定义信息等。

这一切都很棒。现在,我希望我的用户能够从应用程序中删除这些文件。这就是我向南走的地方。

认为我关闭了所有输入流等,但是在应用程序中似乎存在锁定,不允许我删除它。

  • 如果我在我的应用程序的上下文中创建zip文件,我可以删除它。
  • 如果我从文件系统中读取它并且不使用vfs2访问它,我可以删除它。
  • 如果我从文件系统中读取它并使用vfs2访问它,我就不允许删除它。

如果你想创建自己的zip文件来试试它,这里有一个简单的json字符串。

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

将其复制到名为project.json的文件中,然后保存。然后,将其压缩到Java项目根目录中的zip文件中。

以下例子说明了我的困境:

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();
        }
    }
}

1 个答案:

答案 0 :(得分:1)

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;
    }

}