Friday 2 October 2015

Unable to move or delete files after reading it

Applies to: AX2012

Scenario
- Open file and read
- Move the file to another folder after reading is completed

Issue
While not running it in CIL, the code works, but once run it in CIL, it give the error "System.IO.IOException: The process cannot access the file because it is being used by another process".

Those who came from AX 2009 used to depends on AX to finalize an object by just leaving the scope. Ref: https://msdn.microsoft.com/en-us/library/io.finalize.aspx

But when running in CIL, the finalize needs to be called manually.

Below is a sample service class called by a controller, when running the code in CIL, if the 'finalize()' is called, no error occur. But if the 'finalize()' is not called, it give the error as shown above.

=================================================
class DemoService extends SysOperationServiceBase
{
}

=================================================
public void processDemo(DemoDataContract _contract)
{
    ;

    this.processFile(_contract.parmFileNameFrom());
    
    this.moveFile(_contract.parmFileNameFrom(), _contract.parmFileNameTo());
}

=================================================
void processFile(Filename _fileNameFrom)
{
    #File
    FileIoPermission                perm;
    TextIo                          importFile;
    container                       record;
    int                             totalRecords;
    ;

    perm = new FileIoPermission(_fileNameFrom, #io_read);
    perm.assert();

    importFile = new TextIo(_fileNameFrom, #io_read);

    while(importFile.status() ==  IO_Status::Ok)
    {
        record = importFile.read();

        totalRecords++;
    }
        
    if(totalRecords)
        info(strFmt("Row count: %1", totalRecords));

    //importFile.finalize(); //Enable and disable this comment to test the effect
}

=================================================
void moveFile(Filename _sourceFile, Filename _destinationFile)
{
    #File
    FileIoPermission            perm;
    ;

    perm = new FileIoPermission(_destinationFile, #io_write);
    perm.assert();

    System.IO.File::Move(_sourceFile, _destinationFile);
}