saker.build Documentation TaskDoc JavaDoc

Custom files

Creating custom SakerFile implementations are sometimes beneficial as they can be more memory and performance efficient than using some of the built-in implementations. In order to do that, you need to extend the SakerFileBase class, and implement the appropriate methods.

The main purpose of implementing your own SakerFile is to provide a more efficient implementation for providing the backing contents of the file. When generating files, it is often more efficient to just keep the generator data in memory rather than the whole contents of the file.

In the following example we're going to showcase a file implementation that simply generates odd numbers up to a maxmimum separated by new lines as the contents of the file.

The class of the file is the following:

public class OddNumbersSakerFile extends SakerFileBase {
	private OddNumbersContentDescriptor contentDescriptor;

	public OddNumbersSakerFile(String name, int max) {
		super(name);
		this.contentDescriptor = new OddNumbersContentDescriptor(max);
	}

	@Override
	public ContentDescriptor getContentDescriptor() {
		return contentDescriptor;
	}

	@Override
	public void writeToStreamImpl(OutputStream os) 
			throws IOException {
		int max = contentDescriptor.getMax();
		for (int i = 1; i < max; i += 2) {
			os.write(Integer.toString(i).getBytes());
			os.write('\n');
		}
	}

	@Override
	public int getEfficientOpeningMethods() {
		return OPENING_METHODS_ALL;
	}
}

The class takes a maximum integer in its content descriptor which is the limit until the file contents list the odd numbers. The content descriptor class is just a plain ContentDescriptor data class containing the maximum integer.

We must override the abstract writeToStreamImpl method that is responsible for writing the contents of the file to the argument stream. In the example, we write the odd numbers on separate lines to the stream.

In the overridden method getEfficientOpeningMethods() we signal that all content retrieval methods are considered to be efficient. This is related to the implicit synchronization behaviour mentioned in File contents. As we implement the stream writing efficiently, we can consider all related methods to be efficient as all other implementations use this function in the end.

Note: An opening method is considered to be efficient if retrieving the contents consume less resources (time and space) than using the hardware disk.

The above example showcases most of the necessary functionality to implement your own custom file. There are some uncommon extraneous features of the SakerFile interface which you can get familiar with by viewing the interface documentation.