Question

I have to create an application that retrieves a xml file on the web, and stores it on the SD card in a Blackberry phone. The xml file is updated by a cron job. So I want the application to download the new xml file if data has been added to this xml file.

For now I compare all the data files using this piece of code

public static boolean isSame( DataInputStream input1, DataInputStream input2 ) throws IOException {
    boolean error = false;
      try {
          byte[] buffer1 = new byte[1024];
          byte[] buffer2 = new byte[1024];
          try {
              int numRead1 = 0;
              int numRead2 = 0;
              while (true) {
                  numRead1 = input1.read(buffer1);
                  numRead2 = input2.read(buffer2);
                  if (numRead1 > -1) {
                      if (numRead2 != numRead1) return false;
                      // Otherwise same number of bytes read
                      if (!Arrays.equals(buffer1, buffer2)) return false;
                      // Otherwise same bytes read, so continue ...
                  } else {
                      // Nothing more in stream 1 ...
                      return numRead2 < 0;
                  }
              }
          } finally {
              input1.close();

          }
      } catch (IOException e) {
          error = true; // this error should be thrown, even if there is an error closing stream 2
          throw e;
      } catch (RuntimeException e) {
          error = true; // this error should be thrown, even if there is an error closing stream 2
          throw e;
      } finally {
          try {
              input2.close();
          } catch (IOException e) {
              if (!error) throw e;
          }
      }
}

It works perfectly, but takes a long time to run.

So is it possible to read the end of the file to see if changes were made, and if so, re-download it ?

Was it helpful?

Solution

In case you don't find a way to read the end of the file: maybe it is possible to create another "mini" file that contains the end that you want to read. So for example if you want to read the last X bytes, then create a new file and write the last X bytes in it. it goes without saying that this file containing the last X bytes needs to be created/updated every time that the XML file gets created/updated by the cron job.

On the device, you store both The XML and the "mini" file. but now you activate your method above on streams to the "mini" files that are found on the server and on the device. If you find that they are not equal, you download both the XML file and also the mini file and override them on the device.

OTHER TIPS

Why don't you create a file on the server which contains the date of the latest change? Then your Java app downloads just the small file and based on its content it decides if the entire xml-file has to get downloaded. Or isn't that an option?

My understanding of your use case is that you compare the XML files on on the device (blackberry) itself, so before comparision you always download the file to the device.

If the above assumption is true I can't see any reason for comparing the files at all. Simply replace the local file by the (possibly) new server flie and your job is done.

EDIT based on @bulby97 comments:

Why not providing a service that answers the client's question whether to download a new file or not (pseudo code):

Server side

boolean retrieveNewFile(int clientVersion) {
    int serverVersion = getServerVersion();
    if (clientVersion < serverVersion) {
        return true;
    }
    return false;
}

Client side

download() {
    int clientVersion = getClientVersion();
    boolean download = SERVER.retrieveNewFile(clientVersion);

    if (download) {
        // perform download...
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top