I am currently dealing with an app that has several classes which are used to compare files in various formats (xls, csv, xml, html, pdf...). They are all implementing an interface that is defined like this:
public interface ReportComparator {
// compare files (1 - match, 0 - no match, -1 - both files empty)
int compareTwoFiles(InputStream fileA, InputStream fileB) throws IOException;
// gets a list of format-specific differences between two files
List<String> getDifferences(InputStream fileA, InputStream fileB) throws IOException;
}
The specific comparators are instantiated through a class Report
and are later used by a GUI application, that prints the results of the comparison.
Report:
public class Report {
private final String name, format;
private final ReportComparator comparator;
public Report(String name, String format) {
// produce comparator specific for the format
}
ReportComparator getComparator() {
return this.comparator;
}
}
The problem is, when I am dealing with large files I quickly run out of memory when calling getDifferences()
(increasing memory is currently not an option). Therefore, I thought of using something like a python generator
, but I am having trouble visualizing it in java. Since lambdas
allow deferred execution they would be a candidate for that, but would it be possible keeping this API or at least not having to refactor a lot of code (practically writing it from scratch again)?
ReportComparator::getDifferences
to return a stream be okay? You need a return type which isn't required to be strict hereStream
I getStackOverflowError
s, because I add the differences usingStream.concat
in a loop - and it is long. Can you think of a solution to that problem?Supplier
to 'feed' theStream
. The problem now is: how do I keep current position in the file that I am parsing?