I frequently work with large files and implemented a custom iterator to process these files efficiently while minimizing memory usage. The iterator reads each line from a file, parses it into a Message object, and skips invalid entries.
Are there any optimizations or best practices I can apply to this custom iterable implementation to further reduce memory usage or improve its performance? Below is the implementation for reference:
public class MessageIterable implements Iterable<Message> {
private final Logger logger = MessageFileProcessorSingleton.getInstance().getLog();
private final BufferedReader bufferedReader;
private final MessageParserService parserService;
private final PostExceptionTasksHandler postExceptionTasksHandler;
public MessageIterable(
BufferedReader bufferedReader,
PostExceptionTasksHandler postExceptionTasksHandler,
MessageParserService service) {
this.bufferedReader = bufferedReader;
this.postExceptionTasksHandler = postExceptionTasksHandler;
this.parserService = service;
}
@Override
public Iterator<Message> iterator() {
return new Iterator<>() {
Message next;
@Override
public boolean hasNext() {
if (next != null) {
return true;
}
try {
String messageRowJson;
while ((messageRowJson = bufferedReader.readLine()) != null) {
next = parserService.getMessageFromRowJson(messageRowJson);
if (next == null) {
logger.log(Level.SEVERE, "Unable to parse messaeg row");
System.exit(-1);
} else {
return true;
}
}
} catch (IOException e) {
handleInvalidMessage();
}
return false;
}
@Override
public Message next() {
Message current = next;
next = null;
return current;
}
};
}
private void handleInvalidMessage() {
logger.warn("Invalid message encountered. Executing post-exception tasks.");
postExceptionTasksHandler.handle();
}