6

私のプロジェクトには、単純なファイルアップロードフォームとそれを表示するためのリダイレクトのみが含まれています。50 KB未満のファイルをアップロードできますが、100 KBを超えるファイルをアップロードすると、アプリエンジンからIO例外がスローされます。問題がどこにあるのかわかりません。アプリエンジンのフォーム投稿を通じてGoogleCloudストレージにアップロードできるファイルサイズを増やす方法を知っている人はいますか?ファイルサイズは適切に10MB未満で問題ありません。コードスニペットは非常に高く評価されます。ありがとうございました。

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>

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

}

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

}

fileserve.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次の場所から2番目を変更してみてください。

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 に答える