Здесь
ArrayList<Integer> byteArray = new ArrayList<Integer>();
int tempByte;
do {
tempByte = stream.read();
byteArray.add(tempByte);
Вы записываете каждый байт прямо в память в виде массива целых чисел! Каждое целое число занимает 4 байта памяти, в то время как вам нужен только один байт на каждый прочитанный байт. Фактически вы должны использовать ArrayList<Byte>
или лучше byte[]
вместо этого, поскольку каждый byte
стоит только один байт памяти, но при этом каждый раз выделяется столько же памяти, сколько размер файла.
А здесь
byte[] bytes = new byte[byteArray.size()];
впоследствии вы выделяете столько памяти, сколько занимает файл. С другой стороны, вы и ArrayList<Integer>
, и byte[]
выделяете в 5 раз больше памяти, чем размер файла.
Это пустая трата времени.
Вы должны записать это OutputStream
немедленно , например FileOutputStream
.
InputStream input = null;
OutputStream output = null;
try {
input = license.openStream();
output = new FileOutputStream("/file.ext");
byte[] buffer = new byte[1024];
for (int length; (length = input.read(buffer)) > 0;) {
output.write(buffer, 0, length);
}
} finally {
if (output != null) try { output.close(); } catch (IOException logOrIgnore) {}
if (input != null) try { input.close(); } catch (IOException logOrIgnore) {}
}
Это эффективно стоит всего 1 КБ памяти для буфера вместо всей длины файла в байтах (или в 4 раза больше при использовании целых чисел).
Или, если вы действительно хотите иметь его в byte[]
, просто пропустите весь шаг ArrayList<Integer>
. Это не имеет никакого смысла. Используйте ByteArrayOutputStream
как OutputStream
.
InputStream input = null;
ByteArrayOutputStream output = null;
try {
input = license.openStream();
output = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
for (int length; (length = input.read(buffer)) > 0;) {
output.write(buffer, 0, length);
}
} finally {
if (output != null) try { output.close(); } catch (IOException logOrIgnore) {}
if (input != null) try { input.close(); } catch (IOException logOrIgnore) {}
}
byte[] bytes = output.toByteArray();
Это, однако, все еще стоит столько же памяти, сколько размер файла, но теперь он больше не в 5 раз больше размера файла, чем вы изначально делали с ArrayList<Integer>
и byte[]
впоследствии.
Обновление: Согласно вашему комментарию, вы хотите сохранить это в базе данных. Вы также можете сделать это, не сохраняя весь файл в памяти Java. Просто запишите полученный InputStream
немедленно в БД, используя PreparedStatement#setBinaryStream()
.
final String SQL = "INSERT INTO file (filename, contentType, content) VALUES (?, ?, ?)";
String filename = FilenameUtils.getName(license.getName());
InputStream input = license.openStream();
Connection connection = null;
PreparedStatement statement = null;
try {
connection = database.getConnection();
statement = connection.prepareStatement(SQL);
statement.setString(1, filename);
statement.setString(2, getServletContext().getMimeType(filename));
statement.setBinaryStream(3, input);
statement.executeUpdate();
} catch (SQLException e) {
throw new ServletException("Saving file in DB failed", e);
} finally {
if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {}
if (connection != null) try { connection .close(); } catch (SQLException logOrIgnore) {}
}