How do I write to a file Line by Line in a Mendix Java Action

0
 I have a large file that needs to be created. The sum of all the data in the file means that extracting all the data in one go holding it in memory then creating the output stream of all data is not practical, as the server has a memory overload. My solution is to process the rows of data to be written to the file one at a time. The following code will write the whole of the data to the file in one go: Core.storeFileDocumentContent(getContext(), processFile.getMendixObject(), this.fileName, new ByteArrayInputStream(exportFile.getBytes())); I can write to a file one row at a time using Java, but how do I associate the file with the Mendix object (which inherits System.FileDocument  )
asked
2 answers
1

Here a code example

IMendixObject mendixObject = Core.instantiate(getContext(), "moduleName.entityName");

Regards,

Ronald

[EDIT]

Complete example to write some attributes to a file.

// BEGIN USER CODE
Integer attribute11Length = 3;
Integer attribute2Length = 6;
Integer attribute3Length = 50;
Integer attribute4Length = 1;

/* Begin of file writer code */
Writer writer = null;
String EOL = "\r\n";
try {
    File file = new File(ExportPad);
    writer = new BufferedWriter(new FileWriter(file));
    /* Iterate over transactions and write to buffer */
    for ( modulename.proxies.mendixEntity transaction : entityList) {
	writer.write(padString(transaction.getattribute1(), attribute1Length));
	writer.write(padString(transaction.getattribute2(), attribute2Length));
	writer.write(padString(transaction.getattribute3(), attribute3Length));
	writer.write(padString(transaction.getattribute4(), attribute4lLength));
		    			
	writer.write(EOL);
     }
     /* End iterate over transactions */

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (writer != null) {
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
/* End of file writer code */

IMendixObject mendixObject = Core.instantiate(getContext(), "moduleName.entityName");
String text = new Scanner( new File(ExportPad) ).useDelimiter("\\A").next();
InputStream inputStream = new ByteArrayInputStream(text.getBytes());
Core.storeFileDocumentContent(getContext(), mendixObject, inputStream);
return mendixObject;
// END USER CODE

// BEGIN EXTRA CODE
public static String padString(String s, int n) {
	return String.format("%1$-" + n + "s", s);  
}
// END EXTRA CODE

 

answered
0

The ideal would be to be able to get the outputstream

The following creates a 1k x 32k (256Mb) in approximately 15 seconds [local/onprem only]

    var ctx=root.getContext();
    var delim="\\";
    var start=new Date();
    var obj_fd=com.mendix.core.Core.instantiate(ctx,"Imports.FileDocument");
    obj_fd.setValue(
        ctx,
        "Name",
        "Test - FOO.dat"
        );
    //ensure its down on disk
    com.mendix.core.Core.storeFileDocumentContent(
        ctx,
        obj_fd,
        "Test - FOO - "+new Date().toString()+".dat",
        new java.io.ByteArrayInputStream(
            new java.lang.String("").getBytes(java.nio.charset.StandardCharsets.UTF_8)
        )
    );        
    com.mendix.core.Core.commit(ctx,obj_fd);
    var path=
        [
            com.mendix.core.Core.getConfiguration().getBasePath(),
            "data",
            "files",
            obj_fd.getValue(ctx,"__UUID__").substr(0,2),
            obj_fd.getValue(ctx,"__UUID__").substr(2,2),
            obj_fd.getValue(ctx,"__UUID__")
        ].join(delim)
    ;
    var writer = new java.io.FileWriter(new java.io.File(path));
    var bufferedWriter = new java.io.BufferedWriter(writer,1024);
    ncol=Math.pow(2,10);
    nrow=Math.pow(2,15);
    for(var irow=0;irow<nrow;irow++){
        for(var icol=0;icol<ncol;icol++){
            writer.write(
                new String(Math.floor(Math.random()*4096)).paddingLeft("        ")
            );
        }
        writer.write(
            "\n"
        );
    }
    writer.flush();
    writer.close();
    alert(path);
    var end=new Date();
    alert(
        'Created File - '+(end-start)/1000+' s'
    );

 

answered