Похоже, что вы, по сути, хотите создать API, в котором вы сможете поддерживать эффективность потоковой передачи в максимально возможной степени, как вы это делаете при записи файла во время чтения пользовательских данных.
Inв этом случае вы можете захотеть определить API push-parser для ваших ReadSource
s, которые будут передавать данные на ваши WriteTarget
s, которые будут записывать данные во все, для чего у вас есть реализация. Сортировка будет выполняться на стороне ReadSource
, поскольку для некоторых источников вы можете читать упорядоченным образом (например, из баз данных);Для тех источников, для которых вы не можете этого сделать, вы можете просто выполнить промежуточный шаг для сортировки ваших данных (например, записи во временную таблицу) и затем передать их в WriteTarget
.
. Выглядит примерно так:
public class UserDataRecord {
private String data1;
private String data2;
public String getRecordAsString() {
return data1 + "," + data2;
}
}
public interface WriteTarget<Record> {
/** Write a record to the target */
public void writeRecord(Record record);
/** Finish writing to the target and save everything */
public void commit();
/** Undo whatever was written */
public void rollback();
}
public abstract class ReadSource<Record> {
protected final WriteTarget<Record> writeTarget;
public ReadSource(WriteTarget<Record> writeTarget) { this.writeTarget = writeTarget; }
public abstract void read();
}
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class RelationalDatabaseReadSource extends ReadSource<UserDataRecord> {
private Connection dbConnection;
public RelationalDatabaseReadSource (WriteTarget<UserDataRecord> writeTarget, Connection dbConnection) {
super(writeTarget);
this.dbConnection = dbConnection;
}
@Override public void read() {
// read user data from DB and encapsulate it in a record
try (Statement statement = dbConnection.createStatement();
ResultSet resultSet = statement.executeQuery("Select * From TABLE Order By COLUMNS");) {
while (resultSet.next()) {
UserDataRecord record = new UserDataRecord();
// stream the records to the write target
writeTarget.writeRecord(record);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
public class FileWriteTarget implements WriteTarget<UserDataRecord> {
private File fileToWrite;
private PrintWriter writer;
public FileWriteTarget(File fileToWrite) throws IOException {
this.fileToWrite = fileToWrite;
this.writer = new PrintWriter(new FileWriter(fileToWrite));
}
@Override public void writeRecord(UserDataRecord record) {
writer.println(record.getRecordAsString().getBytes(StandardCharsets.UTF_8));
}
@Override public void commit() {
// write trailing records
writer.close();
}
@Override
public void rollback() {
try { writer.close(); } catch (Exception e) { }
fileToWrite.delete();
}
}
Это только общая идея и требует серьезногоулучшение. Любой, пожалуйста, не стесняйтесь обновлять этот API.