При запуске программы с файлом, например, 1Гб вылетает ошибка.
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.base/java.nio.HeapCharBuffer.<init>(HeapCharBuffer.java:61)
at java.base/java.nio.CharBuffer.allocate(CharBuffer.java:348)
at java.base/java.util.Scanner.makeSpace(Scanner.java:915)
at java.base/java.util.Scanner.readInput(Scanner.java:874)
at java.base/java.util.Scanner.findWithinHorizon(Scanner.java:1796)
at java.base/java.util.Scanner.hasNextLine(Scanner.java:1610)
Как правильно считывать большие файлы.
public class Project {
private static Map<Double, String> allAreas = new TreeMap<>();
public static void main(String[] args) {
ReadFile(args[0]);
WriteFile(args[1], SearchMaxArea(allAreas));
for(Map.Entry<Double, String> area : allAreas.entrySet()){
System.out.printf("S = %-5s | Coordinates: %s\n", area.getKey(), area.getValue());
}
}
// Построчное чтение исходного файла
private static void ReadFile(String inputFilename) {
try (Scanner scanner = new Scanner(new File(inputFilename))) {
while (scanner.hasNextLine()) {
String[] numbersStr = scanner.nextLine().split(" ");
if (numbersStr.length == 6)
AreaOfTriangle(numbersStr);
}
} catch (FileNotFoundException e) {
System.out.println("Ошибка чтения! Исходный файл не найден.");
}
}
// Нахождение площади треугольника
private static void AreaOfTriangle(String[] numbersStr) {
int[] c = new int[numbersStr.length];
for (int i = 0; i < c.length; i++)
c[i] = Integer.parseInt(numbersStr[i]);
// нахождение площади по формуле S = ( (x2-x1)*(y3-y1) - (x3-x1)*(y2-y1) ) / 2
double area = (double) Math.abs( (c[2] - c[0]) * (c[5] - c[1]) - (c[4] - c[0]) * (c[3] - c[1]) ) / 2;
allAreas.put(area, String.join(" ", numbersStr));
}
// Поиск треугольника с максимальной площадью
private static String SearchMaxArea(Map<Double, String> areas) {
Map.Entry<Double, String> maxEntry = null;
for (Map.Entry<Double, String> item : areas.entrySet()) {
if (maxEntry == null || item.getKey().compareTo(maxEntry.getKey()) > 0)
maxEntry = item;
}
try {
return maxEntry.getValue();
} catch (NullPointerException e) {
System.out.println("Ошибка! Треугольники в исходном файле отсутствуют.");
return "";
}
}
// Запись результата в новый файл
private static void WriteFile(String outputFilename, String result) {
try (PrintWriter pw = new PrintWriter(new File(outputFilename))) {
pw.println(result);
} catch (FileNotFoundException e) {
System.out.println("Ошибка записи! Файл не найден.");
}
}
}
Не нужно запоминать все треугольники, если нужен только максимальный. Мало того, нет смысла каждый раз делать объединение результирующей строки. Это можно сделать один раз при записи файла. Это сэкономит ресурс. Мало того, вы можете периодически вызывать System.gc() - сборщик мусора. Правда это не гарантирует его запуска, но , как показывает практика, все таки он запускается и чистит память. При таком подходе вы можете читать любой файл , не переполняя память, ведь чтение и так выполняется построчно, но теперь, кроме текущего самого большого про площади треугольника вы ничего не запоминаете. И еще... методы именуются с маленькой буквы и используйте поменьше статики. Удачи
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;
public class Project {
private double maxArea = -1;
private String [] numbers;
private final int CLEAN_COUNTER = 10_000;
public static void main(String[] args) {
Project project = new Project();
project.readFile(args[0]);
project.writeFile(args[1]);
}
// Построчное чтение исходного файла
private void readFile(String inputFilename) {
int count = 0;
try (Scanner scanner = new Scanner(new File(inputFilename))) {
while (scanner.hasNextLine()) {
final String[] numbersStr = scanner.nextLine().split(" ");
if (numbersStr.length == 6) areaOfTriangle(numbersStr);
if (CLEAN_COUNTER<=count) {
System.gc();count=0;
}
count++;
}
} catch (FileNotFoundException e) {
System.out.println("Ошибка чтения! Исходный файл не найден.");
}
}
// Нахождение площади треугольника
private void areaOfTriangle(String[] numbersStr) {
int[] c = new int[numbersStr.length];
for (int i = 0; i < c.length; i++) c[i] = Integer.parseInt(numbersStr[i]);
// нахождение площади по формуле S = ( (x2-x1)*(y3-y1) - (x3-x1)*(y2-y1) ) / 2
double area = Math.abs((c[2] - c[0]) * (c[5] - c[1]) - (c[4] - c[0]) * (c[3] - c[1])) / 2;
searchMaxArea(area, numbersStr);
}
// Поиск треугольника с максимальной площадью
private void searchMaxArea(double area, String[] numbersStr) {
if (this.maxArea < area) {
this.maxArea = area;
this.numbers = numbersStr;
}
}
// Запись результата в новый файл
private void writeFile(String outputFilename) {
if (maxArea==-1) {
System.out.println("Ошибка! Треугольники в исходном файле отсутствуют.");
return;
}
try (PrintWriter pw = new PrintWriter(new File(outputFilename))) {
pw.println(String.join(" ", numbers));
} catch (FileNotFoundException e) {
System.out.println("Ошибка записи! Файл не найден.");
}
}
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
На одном проекте подключенный драйвер работаетНа другом - нет - выводит эту ошибку
Делаю приложение на Cordova и мне нужно работать с БДВ браузере всё работает хорошо, но в эмуляторе отказывается
Решил написать отрывок кода, который выводит innerHTML количество гласных и согласных в строке input, в консоли показывает xereresplit, не знаю в чем проблема