При попытке скачать файл с собственного реализованного http-сервера на Jave бразер дико лагает и скорость низкая
Собственно вот такой вот код:
if(Files.exists(Path.of(HttpServer.directory+path)) && ! Files.isDirectory(Path.of(HttpServer.directory+path))) {
// System.out.println("File exists: "+HttpServer.directory+path);
File f = new File(HttpServer.directory+path);
String header = "HTTP/1.1 200 OK\nContent-type: file/file\nContent-Length: " + f.length() + "\nConnection: close\n\n";
InputStream fileContent = new FileInputStream(f);
out.write(header.getBytes("UTF-8"));
while (fileContent.available() > 0)
out.write(fileContent.read());
out.flush();
}
HttpServer.directory - содержит в себе путь до директории, в которой будет происходить хостинг файлов на http-сервере, она указывается в аргументах запуска, в моем случае это C:/PFB/Server, а path - содержит в себе URI из http-запроса GET.
HttpServer запущен на 8080 порте.
Итак, у меня на ПК содержится файл по пути C:/PFB/Server/asd.exe весом 578 мб, а так же по пути C:/PFB/Server у меня находится еще парочка мелких файлов.
Я захожу в браузер, пытаюсь сначала скачать эту парочку файлов, всё успешно, но когда я ввожу http://localhost:8080/asd.exe, то есть хочу скачать большой файл, у меня браузер начинает дико виснуть, скорость загрузки 20 кб/с, при попытке что-то делать браузер не отвечает.
Может, файл нельзя закидывать целиком в HTTP-ответ? Может, нужно создать несколько TCP соединений?
Нигде данной информации я не нашел.
В чём заключается проблема, и есть ли по этому поводу статьи в интернете?
Ответы (1 шт):
Как уточнили в комментарии, то что при загрузке большого файла, весь файл загружается целиком в оперативную память. Чтобы такого не происходило надо передавать файл частями, в данном случае можно использовать буфер, вот пример:
if (Files.exists(Path.of(HttpServer.directory+path)) && ! Files.isDirectory(Path.of(HttpServer.directory+path))) {
File f = new File(HttpServer.directory+path);
long contentLength = f.length();
String contentType = Files.probeContentType(f.toPath());
String header = "HTTP/1.1 200 OK\nContent-type: " + contentType + "\nContent-Length: " + contentLength + "\nConnection: close\n\n";
out.write(header.getBytes("UTF-8"));
try (InputStream fileContent = new BufferedInputStream(new FileInputStream(f))) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = fileContent.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
}
out.flush();}
Размер буфера выбираем в зависимости от настроенного приема на HTTP сервере.