4.8.10.3. FileLoader Interface

The FileLoader interface allows you to work with file storage using the same set of methods on both middle and client tiers. Uploading and downloading of files is performed using streams:

  • saveStream() – saves an InputStream contents into file storage.

  • openStream() – returns an input stream to load a file contents from file storage.

Tip

Both client-side and server-side implementations of FileLoader follow the common rule: file transfer is always performed by copying data between input and output streams. Files are never fully loaded into memory at any application level, which enables transferring files of almost any size.

As an example of using FileLoader let’s consider a simple task of saving a user input into the text file and displaying the file content in another field on the same screen.

The screen contains two textArea fields. Suppose the user inputs text in the first textArea, clicks the buttonIn below, and the text is saved to the FileStorage. The second textArea will display the content of the saved file on buttonOut click.

Below is the fragment of the screen XML descriptor:

<hbox margin="true"
      spacing="true">
    <vbox spacing="true">
        <textArea id="textAreaIn"/>
        <button id="buttonIn"
                caption="Save text in file"
                invoke="onButtonInClick"/>
    </vbox>
    <vbox spacing="true">
        <textArea id="textAreaOut"
                  editable="false"/>
        <button id="buttonOut"
                caption="Show the saved text"
                invoke="onButtonOutClick"/>
    </vbox>
</hbox>

The screen controller contains two methods invoked on buttons click:

  • In the onButtonInClick() method we create a byte array from the first textArea input. Then we create a FileDescriptor object and define the new file name, extension, size, and creation date with its attributes.

    Then we save the new file with the saveStream() method of FileLoader, passing the FileDescriptor to it and providing the file content with an InputStream supplier. We also commit the FileDescriptor to the data store using the DataManager interface.

  • In the onButtonOutClick() method we extract the content of the saved file using the openStream() method of the FileLoader. Then we display the content of the file in the second textArea.

import com.haulmont.cuba.core.entity.FileDescriptor;
import com.haulmont.cuba.core.global.DataManager;
import com.haulmont.cuba.core.global.FileLoader;
import com.haulmont.cuba.core.global.FileStorageException;
import com.haulmont.cuba.core.global.Metadata;
import com.haulmont.cuba.gui.components.AbstractWindow;
import com.haulmont.cuba.gui.components.ResizableTextArea;
import com.haulmont.cuba.gui.upload.FileUploadingAPI;
import org.apache.commons.io.IOUtils;

import javax.inject.Inject;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;

public class FileLoaderScreen extends AbstractWindow {

    @Inject
    private Metadata metadata;
    @Inject
    private FileLoader fileLoader;
    @Inject
    private DataManager dataManager;
    @Inject
    private ResizableTextArea textAreaIn;
    @Inject
    private ResizableTextArea textAreaOut;

    private FileDescriptor fileDescriptor;

    public void onButtonInClick() {
        byte[] bytes = textAreaIn.getRawValue().getBytes();

        fileDescriptor = metadata.create(FileDescriptor.class);
        fileDescriptor.setName("Input.txt");
        fileDescriptor.setExtension("txt");
        fileDescriptor.setSize((long) bytes.length);
        fileDescriptor.setCreateDate(new Date());

        try {
            fileLoader.saveStream(fileDescriptor, () -> new ByteArrayInputStream(bytes));
        } catch (FileStorageException e) {
            throw new RuntimeException(e);
        }

        dataManager.commit(fileDescriptor);
    }

    public void onButtonOutClick() {
        try {
            InputStream inputStream = fileLoader.openStream(fileDescriptor);
            textAreaOut.setValue(IOUtils.toString(inputStream));
        } catch (FileStorageException | IOException e) {
            throw new RuntimeException(e);
        }
    }
}
fileLoader recipe