Splitting a mendix file into smaller parts

0
I need to split up a file into multiple parts and return a list of these objects. I've tried using allready existing java code from the Misc.java but as I am not java developer I couldnt figure it out. Is there anyone who is able to help me?   ublic class FileSplit extends CustomJavaAction<java.util.List<IMendixObject>> { private IMendixObject __FileDocument; private system.proxies.FileDocument FileDocument; private IMendixObject __FilePartEntity; private microsoftgraphcustom.proxies.FilePart FilePartEntity; public FileSplit(IContext context, IMendixObject FileDocument, IMendixObject FilePartEntity) { super(context); this.__FileDocument = FileDocument; this.__FilePartEntity = FilePartEntity; } @java.lang.Override public java.util.List<IMendixObject> executeAction() throws Exception { this.FileDocument = __FileDocument == null ? null : system.proxies.FileDocument.initialize(getContext(), __FileDocument); this.FilePartEntity = __FilePartEntity == null ? null : microsoftgraphcustom.proxies.FilePart.initialize(getContext(), __FilePartEntity); // BEGIN USER CODE long sourceSize = Misc.getFileSize(this.getContext(),FileDocument.getMendixObject()); ArrayList<IMendixObject> returnList = new ArrayList<IMendixObject>(); //create Mendix list to return int maxReadBufferSize = 320 * 1024; //320kb byte[] buffer = new byte[maxReadBufferSize]; //Core.getFileDocumentContent(this.getContext(),FileDocument.getMendixObject()); try (InputStream is = Core.getFileDocumentContent(this.getContext(),FileDocument.getMendixObject()) BufferedInputStream bis = new BufferedInputStream(is)) { int bytesAmount = 0; while ((bytesAmount = bis.read(buffer)) > 0) { //write each chunk of data into separate file with different number in name IMendixObject newPartEntity = Core.instantiate(this.getContext(),"MicrosoftGraphCustom.FilePart"); // Create new newPartEntity Core.storeFileDocumentContent(this.getContext(), newPartEntity, bis); // Store the content of the buffer to the new part entity returnList.add(newPartEntity); // add entity to the list } } return returnList; //add Object to return list // END USER CODE } /** * Returns a string representation of this action */ @java.lang.Override public java.lang.String toString() { return "FileSplit"; }  
asked
3 answers
0

Hi Luuk,
I had a similar challenge, where I needed to upload a large file into small chunks.
Below is the javacode I used for splitting up the large file.

Java action
Input: 
File – The file you want to split
BlockSize – The size of each block in bytes
Output:
List of SplitBlock – List of smaller blocks 

Datamodel
Offset – Offset of block in the original file.
(e.g. with a BlockSize of 1000, the offset of the blocks will be 0, 1000, 2000 etc..
Length – equals the block size or smaller if it is the last chunk.

Java Action (change the package name myfirstmodule accordingly)

package myfirstmodule.actions;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import com.mendix.core.Core;
import com.mendix.systemwideinterfaces.core.IContext;
import com.mendix.webui.CustomJavaAction;
import org.apache.commons.io.IOUtils;
import myfirstmodule.proxies.SplitBlock;
import com.mendix.systemwideinterfaces.core.IMendixObject;

public class SplitFile extends CustomJavaAction<java.util.List<IMendixObject>>
{
	private IMendixObject __File;
	private system.proxies.FileDocument File;
	private java.lang.Long BlockSize;

	public SplitFile(IContext context, IMendixObject File, java.lang.Long BlockSize)
	{
		super(context);
		this.__File = File;
		this.BlockSize = BlockSize;
	}

	@java.lang.Override
	public java.util.List<IMendixObject> executeAction() throws Exception
	{
		this.File = this.__File == null ? null : system.proxies.FileDocument.initialize(getContext(), __File);

		// BEGIN USER CODE
		List<IMendixObject> result = new ArrayList<IMendixObject>();

		if (this.File == null) {
			throw new IllegalArgumentException("Source file is null");
		}
		if (!this.File.getHasContents()) {
			throw new IllegalArgumentException("Source file has no contents!");
		}
		

		try (InputStream attachment = Core.getFileDocumentContent(getContext(), File.getMendixObject())) {

			byte[] bytes = IOUtils.toByteArray(attachment);
			ByteArrayInputStream bis = new ByteArrayInputStream(bytes);

			long offset = 0;
			long fileSize = bytes.length;
			long length = this.BlockSize.longValue();

			while (offset < fileSize && length > 0) {
				length = offset+this.BlockSize < fileSize ? this.BlockSize.intValue() : fileSize-offset;
			
				SplitBlock block = new SplitBlock(getContext());
				block.setOffset(getContext(), offset);
				block.setLength(getContext(), length);
				block.setContents(getContext(), bis, length);

				result.add(block.getMendixObject());

				offset += length;			
			} 
		} 

		return result;
		// END USER CODE
	}

	/**
	 * Returns a string representation of this action
	 * @return a string representation of this action
	 */
	@java.lang.Override
	public java.lang.String toString()
	{
		return "SplitFile";
	}

	// BEGIN EXTRA CODE
	// END EXTRA CODE
}

 

answered
0

You are passing in a FileDocument and a FilePart to the Java Action. The FilePart isn’t used, so it may be some legacy code that was removed. You can pass empty for that.

The FileDocument you passed is then read, split into 320kb chunks, a new MicrosoftGraphCustom.FilePart object is created for each part, and these objects are added to a list.

This List of MicrosoftGraphCustom.FilePart objects are then returned.

I hope this helps.

answered
0

Hi Nils,

 

I tried using your Java action with the same implementation you did.

I  set the BlockSize to be 1000000 (1MB) and pass a file of size 1987083 (almost 2MB)

I get back a list with two SplitBlock objects, the first object size is 1987083 and the second is 0.
any idea why?

answered