我正在尝试将2mb文件读入内存,然后将该文件发送到Web服务器。但我的内存异常。
FileConnection fileConn = (FileConnection)Connector.open("file:///" + pictureURI.getString(), Connector.READ);
InputStream fis = fileConn.openInputStream();
long overallSize = fileConn.fileSize();
int chunkSize = 2048;
int length = 0;
while (length < overallSize)
{
byte[] data = new byte[chunkSize];
int readAmount = fis.read(data, 0, chunkSize);
byte[] newImageData = new byte[rawImage.length + chunkSize];
System.arraycopy(rawImage, 0, newImageData, 0, length);
System.arraycopy(data, 0, newImageData, length, readAmount);
rawImage = newImageData;
length += readAmount;
}
fis.close();
fileConn.close();
正在上传500kb文件。可能是什么原因?请详细说明。
我也在循环中尝试了这个但没有用,System.gc();
[编辑] https://stackoverflow.com/users/45668/malcolm让我走上正轨。现在我来到这里
this.progress = progress;
HttpConnection conn = null;
OutputStream os = null;
InputStream s = null;
StringBuffer responseString = new StringBuffer();
try
{
System.out.println(System.getProperty("HTTPClient.dontChunkRequests"));
conn = (HttpConnection)Connector.open(url);
//conn.setRequestProperty("User-Agent", "Profile/MIDP-2.1 Configuration/CLDC-1.1");
conn.setRequestMethod(HttpConnection.POST);
// The messages
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=---------------------------4664151417711");
conn.setRequestProperty("Content-Length", "355");
os = conn.openOutputStream();
System.out.println("file name at upload " + fileName);
String message1 = "";
message1 += "-----------------------------4664151417711\r\n";
message1 += "Content-Disposition: form-data; name=\"file\"; filename=\"" + fileName + "\"\r\n";
message1 += "Content-Type: image/gif\r\n";
message1 += "\r\n";
os.write(message1.getBytes());
System.gc();
// Send the image
int index = 0;
int size = 2048;
double progdouble;
do
{
progdouble = ((double)index) / ((double)rawImage.length) * 100;
progress.setValue((int)progdouble);
if((index+size) > rawImage.length)
{
size = rawImage.length - index;
}
os.write(rawImage, index, size);
index += size;
System.gc();
} while(index < rawImage.length);
String message2 = "\r\n-----------------------------4664151417711\r\n";
message2 += "Content-Disposition: form-data; name=\"number\"\r\n\r\n";
message2 += this.user_phone_number;
os.write(message2.getBytes());
String message3 = "\r\n-----------------------------4664151417711\r\n";
message3 += "Content-Disposition: form-data; name=\"uuid\"\r\n\r\n";
message3 += this.user_uuid;
os.write(message3.getBytes());
String message4 = "\r\n-----------------------------4664151417711--\r\n";
os.write(message4.getBytes());
os.flush();
os.close();
// Read
s = conn.openInputStream();
int ch, i = 0, maxSize = 16384;
while(((ch = s.read())!= -1 ) & (i++ < maxSize))
{
responseString.append((char) ch);
}
conn.close();
System.out.println("response =>"+responseString.toString());
return responseString.toString();
}
catch (IOException ioe)
{
return ioe.toString();
}
现在它在这里失败了..
[EDIT2]
// algorithm that will read 1024 bytes at a time
byte b[] = new byte[chunkSize];
for (int i = 0; i < overallSize; i += chunkSize) {
if ((i + chunkSize) < overallSize) {
fis.read(b, 0, chunkSize);
} else {
int left = (int)overallSize - i;
fis.read(b, 0, left);
}
// writing into the output stream - ( these lines will cause the "memory leak", without these, it will not happen)
os.write(b);
System.gc();
progdouble = ((double)i) / ((double)overallSize) * 100;
progress.setValue((int)progdouble);
}
os.flush();
提前致谢。
答案 0 :(得分:3)
您沿途分配了大量新阵列,这是完全没必要的。每个new byte[]
行分配一个新数组。
你应该读入一个大数组,你应该在循环之前分配一次。您可以轻松地执行此操作,因为您知道文件的确切大小。代码看起来像这样:
FileConnection fileConn;
InputStream is;
try {
fileConn = (FileConnection) Connector.open("file:///" + pictureURI.getString(), Connector.READ);
is = fileConn.openInputStream();
long overallSize = fileConn.fileSize();
if (overallSize > Integer.MAX_VALUE) throw new IllegalArgumentException("File is too large);
byte[] imageData = new byte[(int) overallSize];
int chunkSize = 2048;
int bytesReadTotal = 0;
while (bytesRead < overallSize) {
int bytesRead = is.read(imageData, bytesReadTotal, Math.min(imageData.length - bytesReadTotal, chunkSize));
if (bytesRead == -1) break;
bytesReadTotal += bytesRead;
}
} finally {
if (is != null) is.close();
if (fileConn != null) fileConn.close();
}
答案 1 :(得分:3)
您的手机(Nokia x2-01 specs)限制为整个应用的2Mb堆空间。根据这些限制设计您的应用。
一次在内存中使用2Mb bytearray