Skip to Content

In this blog, SAP PI UDF example is been provided for below functionalities:

  1. To read file contents of a file from sap application directory,
  2. here read only those files which names starts with some key words
  3. To archive same file to other sap application directory
  4. Post Archival, delete the file from source path

Java Imports required in UDF as

  • java.io.BufferedReader
    java.io.FileReader
    java.io.IOException

Java UDF Execution Type is “All Values of Queue”

Java UDF Code is as below:

public void file_Read_Move_Delete(ResultList result, Container container)
 throws StreamTransformationException{

String RequestDataStr = "XYZ";  	                //File Name Starting Key
String FilePath_str = "/folder1/folder2/";	        //File directory
String FileArchival_Path = "/folder1/folder2/folder2/";	//File Archival Path
String fileContentStr = "";
boolean StartsWithStr_Found = false;            

File[] dirFiles = new File(FilePath_str).listFiles();
if (dirFiles.length > 0){	              //Check if Directory is not empty 
 for (int i=0; i<dirFiles.length; i++){	      //Loop Iteration for Each File
 String fileNameStr = dirFiles[i].getName();  //Get File Name
 if (fileNameStr.startsWith(RequestDataStr)){ //Check if Filename starts with Key 'XYZ'
  StartsWithStr_Found = true;		      	

  //Start of reading file content --------------------------		          
  BufferedReader br = null;		      		 
  try{ 
   String sCurrentLine; 
   br = new BufferedReader(new FileReader(FilePath_str  + fileNameStr)); 
   while ((sCurrentLine = br.readLine()) != null){
    fileContentStr = fileContentStr + sCurrentLine;
    } 
  } catch (IOException e) {
   e.printStackTrace();
  } finally {
    try {
     if (br != null)br.close();
    } catch (IOException ex) {
   ex.printStackTrace(); }
  }	
  result.addValue(fileContentStr);   //return each file content
  //End of reading file content --------------------------
		      		
		      		
  //Start of File Archival (i.e. move file from one Folder to other folder -----------
  File inputFile = new File(FilePath_str  + fileNameStr);
		      		
  //Start of Method-01 ---------------
  //inputFile.renameTo(new File(FileArchival_Path + file.getName()));
  //End of Method-01 -----------------		      		
		      		
  //Start of Method-02 ---------------		      		
  InputStream inStream = null;
  OutputStream outStream = null; 			

  try{
   File bfile =new File(FileArchival_Path + dirFiles[i].getName()); 
   inStream = new FileInputStream(inputFile);
   outStream = new FileOutputStream(bfile);
		 
   byte[] buffer = new byte[1024]; 
   int length;
   //copy the file content in bytes 
   while ((length = inStream.read(buffer)) > 0){ 
    outStream.write(buffer, 0, length); 
   } 
   inStream.close();
   outStream.close();

  }catch(IOException e){ 
   e.printStackTrace(); 
  }		    				    		

  inputFile.delete();	//Delete same file from Source Folder (i.e. FilePath_str)
 //End of Method-02 ---------------
 //End of File Archival (i.e. move file from one Folder to other folder -------------

  }//End of "fileName check
}// End of Folder for loop
}// End of directory length check

//If no file found
if (StartsWithStr_Found = false){
 result.addValue("File Not found !");
}

}

 

To report this post you need to login first.

2 Comments

You must be Logged on to comment or reply to a post.

  1. Evgeniy Kolmakov

    Hi Dilip!

    Thanks for sharing this. Just a couple of questions:

    1. How do you handle source file encoding in your code?
    2. Why do you use FileReader to get the file contents (as I could see you didn’t perform any additional processing for the file lines) instead of reading input stream to byte array?
    3. Why do you use String object instead of StringBuilder inside the loop?
    4. What happens on message processing restart, if previous attempt is failed due to any reason after the half of files have already been processed and deleted from source location?

    Regards, Evgeniy.

     

    (0) 
    1. Dilip Kumar KrishnaDev Pandey Post author

      Dear Evgeniy Kolmakov

      About above UDF, which is part of a SAP-PI’s “SOAP-TO-FILE Synchronous Inbound” interface scenario, please find below details:

      Business requirement was like,

      • To send SAP CSV files to client’s non-SAP-system based on its FileNaming starting key query
      • Client’s non-SAP-system had in-built technique to consume/read XML based SOAP web-services
      • There was no other way to send files to them.
      • So we created one SAP-PI’s Synchronous SOAP Web-service
      • On each web-service call which were having FileName Starting Keyword in Request Message Payload, we applied UDF’s logic to read/extract File contents and mapped each File’s full content to separate xml element of SOAP Response Message
      • Post Successful read of Each File Content, we archived and deleted already read files from source folder

      Now please find below answers of your queries:

      1. How do you handle source file encoding in your code?
        • Not required in our case, plain CSV files were in our scope
      2. Why do you use FileReader to get the file contents (as I could see you didn’t perform any additional processing for the file lines) instead of reading input stream to byte array?
        • Objective was to read each file’s content and Map them to each XML element of Soap Response Message
      3. Why do you use String object instead of StringBuilder inside the loop?
        • Required to read each File’s contents and return it as a String
      4. What happens on message processing restart, if previous attempt is failed due to any reason after the half of files have already been processed and deleted from source location?
        • As it is a part of Synchronous interface, so restart of message not possible
        • However, if due to some reason, CleintSystem did not receive Soap response Message having file contents, then from archive folder of SAP-App server, file had to be moved to source folder manually, and Web-service need to be re-triggered from Client Location
        • Here Please note, each file is having some unique number its header contents, which is also part of FileName, so in case of failures, we cross check these details for failed one.

      Hope, above details will make more clarity on UDF’s use.

       

      Thanks & Regards,

      Dilip

      (0) 

Leave a Reply