В моем приложении SpringBoot я использовал Spring Integration для загрузки файлов на удаленный SFTP-сервер.
Ниже приведен фрагмент кода, который я использовал для передачи файла на SFTP-сервер.
protected String transfer(String downloadDirectory) {
File[] files = new File(downloadDirectory).listFiles();
byte[] payload = null;
String path = null;
try {
path = getSftpPath(downloadDirectory);
for (int i = 0; i < files.length; i++) {
if (files[i].isFile()) {
payload = Files.readAllBytes(Paths.get(files[i].toURI()));
gateway.upload(payload, files[i].getName(), path);
}
}
} catch (Exception e) {
throw new Exception(e);
}
return path;
}
Объявление метода загрузки и MessageHandler выглядит следующим образом:
@MessagingGateway(asyncExecutor = "sftpAsync")
public interface UploadGateway {
@Gateway(requestChannel = "toSftpChannel")
void upload(@Payload byte[] file, @Header("filename") String filename, @Header("path") String path);
}
@Bean
@ServiceActivator(inputChannel = "toSftpChannel")
public MessageHandler handler() {
SftpMessageHandler handler = new SftpMessageHandler(sftpSessionFactory());
ExpressionParser expressionParser = new SpelExpressionParser();
handler.setRemoteDirectoryExpression(expressionParser.parseExpression("headers['path']"));
handler.setFileNameGenerator(msg -> (String) msg.getHeaders().get("filename"));
handler.setAutoCreateDirectory(true);
return handler;
}
Отлично работает для загрузки файлов на удаленный SFTP-сервер.Но после пары выполнений он начинает показывать
java.lang.OutOfMemoryError: Direct buffer memory
at java.nio.Bits.reserveMemory(Unknown Source)
at java.nio.DirectByteBuffer.<init>(Unknown Source)
at java.nio.ByteBuffer.allocateDirect(Unknown Source)
at sun.nio.ch.Util.getTemporaryDirectBuffer(Unknown Source)
at sun.nio.ch.IOUtil.read(Unknown Source)
at sun.nio.ch.FileChannelImpl.read(Unknown Source)
at sun.nio.ch.ChannelInputStream.read(Unknown Source)
at sun.nio.ch.ChannelInputStream.read(Unknown Source)
at sun.nio.ch.ChannelInputStream.read(Unknown Source)
at java.nio.file.Files.read(Unknown Source)
at java.nio.file.Files.readAllBytes(Unknown Source)
payload = Files.readAllBytes(Paths.get(files[i].toURI()));
- это строка, в которую выдается указанное выше сообщение об ошибке.
Насколько я понимаю, я читаю весь файл в байтмассив, следовательно, я получаю эту ошибку.Поскольку мне нужен весь файл для отправки в метод загрузки, я следовал подходу byte [].
Я уже проверил ниже упомянутые темы.
Byte [] и java.lang.OutOfMemoryErrorчтение файла по битам
java.lang.OutOfMemoryError: прямая буферная память при вызове Files.readAllBytes
, но для метода загрузки требуется весь файл вместо потокабайты или порции данных (поправьте меня, если я ошибаюсь).
Так что любые предложения, чтобы избежать вышеупомянутой проблемы, очень помогают.
Спасибо.