在Appengine(Java)中将数据写入CSV文件并进行压缩

4

我目前正在开发一个使用Java在Google Appengine上完成的项目。

Appengine不允许存储文件,因此不能使用任何磁盘表示对象,其中包括File类。

我想将数据写入几个CSV文件中,并将其压缩,然后允许用户下载。

如何在不使用任何File类的情况下实现这一点?我在文件处理方面经验不太丰富,希望你们能给我建议。

谢谢。

2个回答

9
您可以在用户下载时创建一个zip文件并将其添加到其中。如果您正在使用servlet,则这很简单:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    // ..... process request

    // ..... then respond
    response.setContentType("application/zip");
    response.setStatus(HttpServletResponse.SC_OK);

    // note : intentionally no content-length set, automatic chunked transfer if stream is larger than the internal buffer of the response
    ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream());

    byte[] buffer = new byte[1024 * 32];
    try {
            // case1: already have input stream, typically ByteArrayInputStream from a byte[] full of previoiusly prepared csv data

            InputStream in = new BufferedInputStream(getMyFirstInputStream());
            try {
                zipOut.putNextEntry(new ZipEntry("FirstName"));

                int length;
                while((length = in.read(buffer)) != -1) {
                    zipOut.write(buffer, 0, length);
                }

                zipOut.closeEntry();
            } finally {
                in.close();
            }

            // case 2: write directly to output stream, i.e. you have your raw data but need to create csv representation

            zipOut.putNextEntry(new ZipEntry("SecondName"));

            // example setup, key is to use the below outputstream 'zipOut' write methods
            Object mySerializer = new MySerializer(); // i.e. csv-writer
            Object myData = getMyData(); // the data to be processed by the serializer in order to make a csv file

            mySerizalier.setOutput(zipOut);

            // write whatever you have to the zipOut
            mySerializer.write(myData);

            zipOut.closeEntry();

            // repeat for the next file.. or make for-loop

        }
    } finally { 
        zipOut.close();
    }
}

除非你有内存限制,否则没有理由将数据存储在文件中。文件可以提供InputStream和OutputStream,它们都具有内存中的等效物。

请注意,创建CSV编写器通常意味着像这样做些什么,其中要点是将一段数据(ArrayList或Map,你拥有的任何数据)转换为byte[]部分。使用DataOutputStream(如果喜欢也可以自己制作)或OutputStreamWriter之类的工具将byte[]部分附加到OutputStream中。


嗨,感谢您的帮助!真的很有用。但是,您能否向我展示如何使用条纹框架来完成此操作?另外,我该如何具体完成这部分内容?Object mySerializer = new MySerializer(); //即csv-writer Object myData = getMyData(); - Adrian
不,我不使用Strips框架,但欢迎在论坛中提出另一个问题;如果您能在Strips中找到一个outputstream,那可能就是您想要的。请参见附加评论。 - ThomasRS

3
如果您的数据不是很大,也就是可以在内存中保存,那么导出为CSV格式并进行压缩,然后通过流式传输下载,这些都可以实时完成。缓存可以在这些步骤中的任何一个步骤中进行,这主要取决于您应用程序的业务逻辑。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接