6

我的项目仅包含简单的文件上传表单和查看它的重定向。我可以上传任何小于 50 KB 的文件,但是当我上传一些大于 100 KB 的文件时,它会从应用引擎抛出 IO 异常。我不确定问题出在哪里。有谁知道如何通过应用引擎中的表单发布来增加我可以上传到谷歌云存储的文件大小?文件大小适当小于 10 MB 即可。任何代码片段将不胜感激。谢谢你。

java.io.IOException
    at com.google.appengine.api.files.FileServiceImpl.translateException(FileServiceImpl.java:615)
    at com.google.appengine.api.files.FileServiceImpl.makeSyncCall(FileServiceImpl.java:588)
    at com.google.appengine.api.files.FileServiceImpl.append(FileServiceImpl.java:535)
    at com.google.appengine.api.files.FileServiceImpl.append(FileServiceImpl.java:289)
    at com.google.appengine.api.files.FileWriteChannelImpl.write(FileWriteChannelImpl.java:57)
    at com.google.appengine.api.files.FileWriteChannelImpl.write(FileWriteChannelImpl.java:46)
    at java.nio.channels.Channels.write(Channels.java:80)
    at java.nio.channels.Channels.access$000(Channels.java:64)
    at java.nio.channels.Channels$1.write(Channels.java:151)
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
    at storefile.StorageService.storeFile(StorageService.java:46)
    at storefile.UploadServlet.doPost(UploadServlet.java:46)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

以下是我的代码:upload.html

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Hello App Engine</title>
</head>

<body>
    <h1>Hello App Engine!</h1>
    <form action="/upload" method="post" enctype="multipart/form-data">
        <p>File<input type="file" name="file" /> </p>
        <p> <input type="submit"value="upload" /> <input type="reset" value="reset"/> </p>
    </form>
  </body>
</html>

上传Servlet.java

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.google.appengine.api.blobstore.BlobKey;


public class UploadServlet extends HttpServlet{

   private static final long serialVersionUID = 1L;
  private StorageService storage = new StorageService();
  private static int BUFFER_SIZE =1024 * 1024* 10;
  @Override
   public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {

      resp.setContentType("text/plain");
      resp.getWriter().println("Now see here your file content, that you have uploaded on storage..");

      ServletFileUpload upload = new ServletFileUpload();
      FileItemIterator iter; 
   try {
    iter = upload.getItemIterator(req);
     while (iter.hasNext()) {
            FileItemStream item = iter.next();
            String fileName = item.getName();
            String mime = item.getContentType();

            storage.init(fileName, mime);
            InputStream is = new BufferedInputStream(item.openStream());

             byte[] b = new byte[BUFFER_SIZE];
            int readBytes = is.read(b, 0, BUFFER_SIZE);

            while (readBytes != -1) {
                storage.storeFile(b, readBytes);
                readBytes = is.read(b, 0, readBytes);
            }

             is.close();
            storage.destroy();

       resp.getWriter().println("File uploading done");

            // resp.getWriter().println("READ:" + storage.readTextFileOnly(fileName));
            BlobKey key = storage.getBlobkey(fileName);
            if (key != null) {
                resp.sendRedirect("/serve?blob-key=" + key.getKeyString());
            } else {
                resp.sendRedirect("/");
            }


      }
   } catch (Exception e) {
    e.printStackTrace(resp.getWriter());
    System.out.println("Exception::"+e.getMessage());
    e.printStackTrace();
   }
 }

}

存储服务.java

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.nio.channels.Channels;
import java.util.logging.Logger;

import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreService;
import com.google.appengine.api.blobstore.BlobstoreServiceFactory;
import com.google.appengine.api.files.AppEngineFile;
import com.google.appengine.api.files.FileReadChannel;
import com.google.appengine.api.files.FileService;
import com.google.appengine.api.files.FileServiceFactory;
import com.google.appengine.api.files.FileWriteChannel;
import com.google.appengine.api.files.GSFileOptions.GSFileOptionsBuilder;

public class StorageService {

public static final String BUCKET_NAME = "aaaa";  

private FileWriteChannel writeChannel = null;
FileService fileService = FileServiceFactory.getFileService();

private BufferedOutputStream bos = null;
private static final Logger log = Logger.getLogger(StorageService.class.getName());
private BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
public void init(String fileName, String mime) throws Exception {
 System.out.println("Storage service:init() method:  file name:"+fileName+" and mime:"+mime);
 log.info("Storage service:init() method:  file name:"+fileName+" and mime:"+mime);

    GSFileOptionsBuilder builder = new GSFileOptionsBuilder()
            .setAcl("public_read")
            .setBucket(BUCKET_NAME)
            .setKey(fileName)
            .setMimeType(mime);  
    AppEngineFile writableFile = fileService.createNewGSFile(builder.build());

    boolean lock = true;
    writeChannel = fileService.openWriteChannel(writableFile, lock);
    bos = new BufferedOutputStream(Channels.newOutputStream(writeChannel));
}

public void storeFile(byte[] b, int readSize) throws Exception { 
    bos.write(b,0,readSize);
    bos.flush();
}

    public void destroy() throws Exception {
     log.info("Storage service: destroy() method");
        bos.close();
        writeChannel.closeFinally();
    }
    public BlobKey getBlobkey (String filename) {
        BlobKey bk = blobstoreService.createGsBlobKey("/gs/aaaa/"+filename);
        return bk;
    }

}

文件服务.java

import java.io.IOException;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreService;
import com.google.appengine.api.blobstore.BlobstoreServiceFactory;

public class fileserve extends HttpServlet {
    private BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();

public void doGet(HttpServletRequest req, HttpServletResponse res)
    throws IOException {
        BlobKey blobKey = new BlobKey(req.getParameter("blob-key"));
        blobstoreService.serve(blobKey, res);
    }
}

web.xml

<?xml version="1.0" encoding="utf-8" standalone="no"?><web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <servlet>
        <servlet-name>upload</servlet-name>
        <servlet-class>storefile.UploadServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>upload</servlet-name>
        <url-pattern>/upload</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>serve</servlet-name>
        <servlet-class>storefile.fileserve</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>serve</servlet-name>
        <url-pattern>/serve</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
4

1 回答 1

7

尝试从以下更改第二个is.read

readBytes = is.read(b, 0, readBytes);

至:

readBytes = is.read(b, 0, BUFFER_SIZE);

如果在某些时候您阅读速度更快,那么数据可用,readBytes设置为0并且它永远保持在这个值,因为它基本上是在做is.read(b, 0, 0).

更好的是 - 你应该检查是否有数据要写入:

while (readBytes != -1) {
    if(readBytes > 0)
        storage.storeFile(b, readBytes);
    readBytes = is.read(b, 0, BUFFER_SIZE);
}
于 2012-12-12T11:00:45.687 回答