2012-12-12 4 views
6

Mój projekt zawiera tylko prosty formularz do przesyłania plików i przekierowanie do wyświetlenia. Mogę przesłać dowolne pliki o rozmiarze mniejszym niż 50 KB, ale gdy przesyłam niektóre pliki większe niż 100 KB, wyrzucam Wyjątek IO z silnika aplikacji. Nie jestem pewien, gdzie jest problem. Czy ktoś wie, jak zwiększyć rozmiar pliku, który mogę przesłać do Google Cloud Storage za pośrednictwem formularza umieszczonego w silniku aplikacji? Rozmiar pliku poprawnie mniejszy niż 10 MB jest prawidłowy. Wszelkie fragmenty kodu będą vhighly docenione. Dziękuję Ci.Dlaczego nie mogę przesłać pliku do Google Cloud Storage o wielkości przekraczającej 100 KB za pośrednictwem aparatu aplikacji?

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) 

Po to mój kod: 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> 

Odpowiedz

7

Spróbuj zmienić drugą is.read z:

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

do:

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

Jeśli w pewnym momencie czytasz szybciej niż dane jest dostępny, readBytes jest ustawiony na 0 i pozostaje na zawsze z tą wartością, ponieważ w zasadzie robi to is.read(b, 0, 0).

Nawet lepiej - należy sprawdzić, czy istnieją dane mają być zapisane:

while (readBytes != -1) { 
    if(readBytes > 0) 
     storage.storeFile(b, readBytes); 
    readBytes = is.read(b, 0, BUFFER_SIZE); 
} 
Powiązane problemy