3.10.8.3. Интерфейс FileLoader

Интерфейс FileLoader предоставляет единый набор методов для работы с файловым хранилищем как на уровне Middleware, так и на клиентском уровне. Загрузка и выгрузка данных осуществляется с помощью потоков:

  • saveStream() – сохраняет содержимое потока InputStream в хранилище.

  • openStream() – возвращает входной поток для выгрузки содержимого файла из хранилища.

И на клиентской и на серверной стороне FileLoader работает по общему принципу: передача файлов осуществляется путём копирования данных между потоками ввода-вывода. Файлы никогда не загружаются в память целиком ни на каком уровне приложения, что позволяет передавать файлы практически любого размера.

В качестве примера использования FileLoader представим, что нам нужно сохранять текст, введённый пользователем, в текстовый файл и отображать содержимое этого файла в другом поле на том же экране.

Экран содержит два поля textArea. Пользователь вводит текст в первое поле textArea, затем нажимает на кнопку buttonIn, и текст сохраняется в хранилище FileStorage. Второе поле будет отображать содержимое сохраненного файла по нажатию кнопки buttonOut.

Ниже представлен фрагмент XML-дескриптора экрана:

<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>

Контроллер экрана содержит два метода, вызываемых при нажатии кнопок под текстовыми полями:

  • В методе onButtonInClick() мы создаём байтовый массив из ввода в первом текстовом поле. Затем создаём объект FileDescriptor и с помощью его атрибутов указываем имя нового файла, его расширение, размер и дату создания.

    После этого мы сохраняем новый файл методом saveStream() интерфейса FileLoader, передав в него объект FileDescriptor и содержимое файла с поставщиком InputStream. Также делаем коммит объекта FileDescriptor в data store с помощью интерфейса DataManager.

  • В методе onButtonOutClick() мы получаем содержимое сохранённого файла методом openStream() интерфейса FileLoader. Затем отображаем содержимое во втором поле 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