How can I create a Global FileInputStream object, which will be available to access from other class within in my project?

StackOverflow https://stackoverflow.com/questions/21680005

Frage

What I wanted to do is create a global FileInputStream object and use it a long of my application.

I have the follow class which create my FileInputStream objec and return the result of my query over the XML file:

package Engine;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList; 
import com.ximpleware.AutoPilot;
import com.ximpleware.VTDException;
import com.ximpleware.VTDGen;
import com.ximpleware.VTDNav;

public class BACENGQueryXMLbyVTD {
  public String query;
   public String path;
    public BACENGQueryXMLbyVTD(String query, String path) {
     this.query = query;
     this.path = path;
}
public ArrayList query() throws IOException, VTDException {
    System.out.println(path);
    File f = new File(path);
    //System.out.println(f);
    FileInputStream fis = new FileInputStream(f);
    //System.out.println(fis);
    byte[] xmlContent = new byte[(int) f.length()];
    fis.read(xmlContent);
    VTDGen vg = new VTDGen();
    vg.setDoc(xmlContent);
    vg.parse(false);
    VTDNav vn = vg.getNav();
    AutoPilot ap = new AutoPilot(vn);
    int node = 0;
    ap.selectXPath(query);
    int i;
    ArrayList<String> interfaces = new ArrayList<String>();
    while ((i = ap.evalXPath()) != -1) {
        vn.push();
        interfaces.add(vn.toString(i + 1));
    }
    ap.resetXPath();
    return interfaces;
}
}

This class is called from my main class which has a loop.

 for (int c = 0; c < nodeNames.size(); c++) {
 String Queries2 = "/import_data/group/node[@name='" +nodeNames.get(c) + "']/interface/@network_value";
 BACENGQueryXMLbyVTD getNodesInterfaces = new BACENGQueryXMLbyVTD(Queries2, TransitPath);
 listOfNodeInterfaces = getNodesInterfaces.query();
}

It's working fine, however in order to reduce the consume of IO resource over my server HD. I would like to create an unique FileInputStream object and use it for each query whcih has to be executed.

Could somebody point out the way to do it?

War es hilfreich?

Lösung

Separate your concerns - BACENGQueryXMLbyVTD is both loading the data and executing the query.

First load the file into a byte[] outside your loop, then pass it to BACENGQueryXMLbyVTD. You might also want to pass the query as an argument to the query method.

You'll end up with a BACENGQueryXMLbyVTD that looks like this (with the disclaimer that I'm not familiar with VTD-XML, so this might the creation of objects from that API might not work exactly like this):

public class BACENGQueryXMLbyVTD 
{
  private byte[] doc;


  public BACENGQueryXMLbyVTD(byte[] doc) 
  {
    this.doc = doc;
  }

  public List<String> query(String query) throws IOException, VTDException 
  {
    VTDGen generator = new VTDGen();
    generator.setDoc(doc);
    generator.parse(false);

    VTDNav navigator = generator.getNav();

    AutoPilot autoPilot = new AutoPilot(navigator);
    autoPilot.selectXPath(query);

    List<String> nodeInterfaces = new ArrayList<String>();

    int i;
    while ((i = autoPilot.evalXPath()) != -1) 
    {
      navigator.push();
      nodeInterfaces.add(navigator.toString(i + 1));
    }

    return nodeInterfaces;
  }
}

That you can then call like:

byte[] xmlContent = ... //load the xml from anywhere you like, not just a file as previously.

BACENGQueryXMLbyVTD getNodesInterfaces = new BACENGQueryXMLbyVTD(xmlContent);

for (String nodeName : nodeNames) 
{
  String query = "/import_data/group/node[@name='" + nodeName + "']/interface/@network_value";
  nodeInterfaces = getNodesInterfaces.query(query);
  ...
}

You might also want to switch to the standard Java XPATH APIs - they're a lot clearer and better documented than VTD-XML.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top