1

I am reading SWIFT Message (MT103) and loading them to a database. Afterwards I need to delete the file so as to avoid a second parsing in the next cycles. But it seams prowide does not Automatically close the InputStream after parsing the message. How can I close the InputStream so that the Files can be archived successfully? When I attempt to Archive the files using FileUtils I get error: Failed to delete original file '\home\swift\991904100973103097.out' after copy to '\home\Outswift\991904100973103097.out'

public static void loadMessageInformationToDatabase(String sourceDir, File archiveDir) {
    log.debug("Listening to Incoming SWIFT Messages");
    File[] files = new File(sourceDir).listFiles();
    log.debug("Found " + files.length + " SWIFT Files for Processing");
    if (files.length > 0) {
        for (int i = 0; i < files.length; i++) {
            log.debug("Attepting to process file " + files[i].getAbsolutePath());
            int swiftSerialNumner = 0;
            try {
                MtSwiftMessage msg = MtSwiftMessage.parse(files[i]);
                String mtNumber = msg.getMessageType();
                String receiver = msg.getReceiver();
                String sender = msg.getSender();
                byte[] message = IOUtils.toByteArray(new FileInputStream(files[i]));
                String pde = msg.getPde();
                String instructedCurrency = "";
                double instructedAmount = 0.00;
                String inOutIndicator = "";
                if (msg.isIncoming()) {
                    inOutIndicator = "I";
                } else if (msg.isOutgoing()) {
                    inOutIndicator = "O";
                }
                String senderReference = "";
                if (mtNumber.equalsIgnoreCase("103")) {
                    MT103 model = MT103.parse(files[i]);
                    List<Field> fields = model.getFields();
                    for (Field field : fields) {
                        if (field.getName().equalsIgnoreCase("20")) {
                            senderReference = field.getValue();
                        }
                        if (field.getName().equalsIgnoreCase("33B")) {
                            instructedCurrency = field.getValue().substring(0, 3);
                            instructedAmount = Double.parseDouble(field.getValue().substring(3).replace(",", "."));
                        }
                    }
                }
                swiftSerialNumner = Swift.addSwiftMessage(mtNumber, receiver, message, "N", null, null, null, null, "S", "SYSTEM", new Date(), "Y", new Date(), "SYSTEM", new Date(), "SYSTEM", null, inOutIndicator, null, null, null, pde, "Y", receiver, sender, null, senderReference, null, instructedAmount, instructedCurrency, null, null, null, null, null, "N", "Y", "N", Gct.getBankId(), "Y");
                if (swiftSerialNumner > 0) {
                    log.debug("File " + files[i].getAbsolutePath() + " Parsed Successfully");
                    if (Swift.isDuplicateReference(senderReference)) {
                        Swift.markSwiftMessageAsDuplicate(swiftSerialNumner);
                        log.warn("SWIFT Serial " + swiftSerialNumner + " Marked as Duplicate");
                    }
                } else {
                    log.error("Error in Parsing File Name " + files[i].getAbsolutePath());
                }

                FileUtils.moveFileToDirectory(files[i], archiveDir, true);//Error comes on this line
                log.debug("SWIFT File " + files[i] + " archived in " + archiveDir.getAbsolutePath());
            } catch (IOException | NumberFormatException asd) {
                log.error("SWIFT Processing Error: " + asd.getMessage());
            }
        }
    }
}
Stanley Mungai
  • 4,044
  • 30
  • 100
  • 168

1 Answers1

2

try this:

FileInputStream fis = new FileInputStream(files[i])
byte[] message = IOUtils.toByteArray(fis);

and add finally clause with closing of fis:

} catch (IOException | NumberFormatException asd) {
    log.error("SWIFT Processing Error: " + asd.getMessage());
} finally {
    fis.close()
}
Lukas Novicky
  • 921
  • 1
  • 19
  • 44
  • Hi, I'm part of Prowide. As a general design principle, the library closes its own opened streams. However, if a stream is passed as parameter, it is assumed to be a responsibility of the caller code to close it. Basically the code that opens it, must close it. Besides that, notice the "byte[] message" is not passed as parameter to the Prowide model. It is used by the custom Swift.addSwiftMessage. The Prowide call receives the File. Finally (out of topic), you can avoid the internal loop in your code and just call model.getField20() for example. – Sebastian Zubrinic Aug 24 '22 at 14:24