[英]Why I can't upload file to Google Cloud Storage that larger than 100KByte through app engine?
My project contains only simple file upload form and the redirect to view it. 我的项目只包含简单的文件上传表单和重定向来查看它。 I can upload any files less than 50 KB but when I upload some files larger than 100 KB, it throws IO Exception from app engine.
我可以上传任何小于50 KB的文件但是当我上传一些大于100 KB的文件时,它会从应用引擎中抛出IO Exception。 I am not sure where the problem is.
我不确定问题出在哪里。 Do anyone know how to increase the file size that I can upload to Google Cloud storage through the form posting in app engine?
有谁知道如何通过应用引擎中的表单发布来增加我可以上传到Google云端存储的文件大小? file size properly less than 10 MB is OK.
文件大小正确小于10 MB是可以的。 Any code snippets would be vhighly appreciated.
任何代码片段都会受到高度赞赏。 Thank you.
谢谢。
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)
Following is my code: upload.html 以下是我的代码: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 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 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 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 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>
Try changing the second is.read
from: 尝试更改第二个
is.read
:
readBytes = is.read(b, 0, readBytes);
to: 至:
readBytes = is.read(b, 0, BUFFER_SIZE);
If at some point you are reading faster then data is available, readBytes
is set to 0
and it stays forever at this value, because it's basically doing is.read(b, 0, 0)
. 如果在某些时候你读得更快然后数据可用,
readBytes
被设置为0
并且它永远保持在这个值,因为它基本上是在做is.read(b, 0, 0)
。
Even better - you should check if there is data to be written: 更好的是 - 您应该检查是否有要写入的数据:
while (readBytes != -1) {
if(readBytes > 0)
storage.storeFile(b, readBytes);
readBytes = is.read(b, 0, BUFFER_SIZE);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.