JAVA app that writes XML Files

I am having problem. When my java app goes to write the XML stream to file it jumps the processor to 100% usage and causes the sytem to come to a complete hault. If the file actually writes the file it does great when its 30k or under but when it receives 1mb of data to write the app seem to have some issue with releasing the memory it was using to write the file or something of that nature.... Example: I can write 5000 x 5k files with no problem. But throw 1 x 2 mb file in there and the whole system goes nuts and will either stop writing or timeout saying it unable to write to file. Here is the code... Is there a better way to do this?

import java.io.*;

public class XMLWriter
{

    public XMLWriter()
    {
    }

    public static void writeXML(String s)
    {
        String s1 = getFileName(s);
        try
        {
            FileOutputStream fileoutputstream = new FileOutputStream(pathToDirectory + s1);
            fileoutputstream.write(s.getBytes());
            fileoutputstream.flush();
            fileoutputstream.close();
        }
        catch(FileNotFoundException filenotfoundexception)
        {
            filenotfoundexception.printStackTrace();
        }
        catch(IOException ioexception)
        {
            ioexception.printStackTrace();
        }
    }

    private static String getFileName(String s)
    {
        int i = s.indexOf("<KEYWORD>") + 9;
        int j = s.indexOf("</KEYWORD>");
        if(i == 8 || j == -1)
        {
            return "KeywordNotPresent";
        } else
        {
            String s1 = s.substring(i, j) + ".xml";
            return s1;
        }
    }

    private static String pathToDirectory = "./xmlfiles/";

}
LVL 3
jsuttorAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jsuttorAuthor Commented:
Note: Though if I eliminate the writing of the files and just display it to the screen no matter how big the files are it works great.
0
StillUnAwareCommented:
Instead of

FileOutputStream fileoutputstream = new FileOutputStream(pathToDirectory + s1);

use this:

BufferedWriter fileoutputstream = new BufferedWriter(new FileWriter(pathToDirectory + s1));
0
rama_krishna580Commented:
Hi,

Java Architecture for XML Binding (JAXB) provides a convenient way to bind an XML schema to a representation in Java code. This makes it easy for you to incorporate XML data and processing functions in applications based on Java technology without having to know much about XML itself.

JAXB 2.0, available in the Java Web Services Developer Pack 2.0, is part of the new integrated stack for Web services development. This new version of JAXB includes all the data binding functionality in a single package, while the previous Web services development stack (in Java WSDP 1.6 and previous versions) carried out some data binding in the JAX-RPC 1.x package and some in the JAXB 1.x package. With the integrated stack comprising JAX-WS 2.0, JAXB 2.0, and SAAJ 1.3, the Web services description, data binding, and SOAP attachment processing functionality are more logically architected, enabling you to develop Web services and Web applications more easily.

https://jaxb.dev.java.net/
http://java.sun.com/webservices/jaxb/index.jsp

R.K
0
Cloud Class® Course: SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

rama_krishna580Commented:
0
Tommy BraasCommented:
The problem is that you're reading the full contents of the XML into memory in a String. I would suggest you use either a BufferedReader or a RandomAccessFile and scan the file for the data you seek.
0
Tommy BraasCommented:
Basically, you need to do two passes of each file. The first pass to determine if the <KEYWORD> tag is present. If it is, you have the file name you need. The second pass would copy the contents of the source file to the destination file, without reading the full contents into memory.
0
jsuttorAuthor Commented:
OK I will be having someone help me with trying all of your suggestions. Thank you.  Since my knowledge of java programming is very limited I need some help so once I get the help I will test these suggestions and let you know the outcome. If someone is interested in writing a better way to do this to help me out I would be very grateful. Since I am not sure when my friend will be able to help.
0
Tommy BraasCommented:
Something like the following should do you well:


class XMLWriter
{
      static final char[] OPEN_TAG = {'<','K','E','Y','W','O','R','D','>'};
      static final char[] CLOSE_TAG = {'<','/','K','E','Y','W','O','R','D','>'};
      private static String pathToDirectory = "./xmlfiles/";
      static final byte[] BUFFER = new byte[8192];
      
      public static void writeXML(RandomAccessFile sourceFile)
      {
            String s1 = getFileName(sourceFile);
            try
            {
                  FileOutputStream fileoutputstream = new FileOutputStream(pathToDirectory + s1);
                  
                  int len = 0;
                  for (long i = 0; i < sourceFile.length(); i += len ) {
                        len = sourceFile.read(BUFFER);
                        if (len > 0) {                              
                              fileoutputstream.write(BUFFER, 0, len);
                        }
                  }
                  fileoutputstream.flush();
                  fileoutputstream.close();
            }
            catch(FileNotFoundException filenotfoundexception)
            {
                  filenotfoundexception.printStackTrace();
            }
            catch(IOException ioexception)
            {
                  ioexception.printStackTrace();
            }
      }
      
      private static String getFileName(RandomAccessFile sourceFile) {
            sourceFile.seek(0);
            boolean openTagFound = true;
            long beginIndex = fileIndexOf(sourceFile, OPEN_TAG);
            long endIndex = fileIndexOf(sourceFile, CLOSE_TAG);
            
            if(beginIndex == -1 || endIndex == -1) {
                  return "KeywordNotPresent";
            }

            StringBuffer filename = new StringBuffer();
            sourceFile.seek(beginIndex + OPEN_TAG.length);
            
            for (long i = beginIndex; i < endIndex; i++ ) {
                  filename.append(sourceFile.readChar());
            }
            return filename.toString();
      }
      

      private static long fileIndexOf(RandomAccessFile sourceFile, final char[] match) {
            boolean matchFound = true;
            sourceFile.seek(0);
            for (long i = 0; i < sourceFile.length(); i++ ) {
                  for (int j = 0; j < match.length; j++ ) {
                        if ( match[j] == sourceFile.readChar() ) {
                              continue;
                        }
                        matchFound = false;
                  }
                  if ( matchFound ) {
                        break;
                  }
            }
            if ( !matchFound ) {
                  return -1;
            }
            long finalIndex = sourceFile.getFilePointer() - match.length;
            if (finalIndex < 0) {
                  finalIndex = -1;
            }
            
            return finalIndex;
      }
}
0
jsuttorAuthor Commented:
orangehead911 your code has some errors

/tmp/2037/XMLWriter.java:8: cannot resolve symbol
symbol  : class RandomAccessFile
location: class XMLWriter
     public static void writeXML(RandomAccessFile sourceFile)
                                 ^
/tmp/2037/XMLWriter.java:35: cannot resolve symbol
symbol  : class RandomAccessFile
location: class XMLWriter
     private static String getFileName(RandomAccessFile sourceFile) {
                                       ^
/tmp/2037/XMLWriter.java:55: cannot resolve symbol
symbol  : class RandomAccessFile
location: class XMLWriter
     private static long fileIndexOf(RandomAccessFile sourceFile, final char[] match) {
                                     ^
/tmp/2037/XMLWriter.java:13: cannot resolve symbol
symbol  : class FileOutputStream
location: class XMLWriter
               FileOutputStream fileoutputstream = new FileOutputStream(pathToDirectory + s1);
               ^
/tmp/2037/XMLWriter.java:13: cannot resolve symbol
symbol  : class FileOutputStream
location: class XMLWriter
               FileOutputStream fileoutputstream = new FileOutputStream(pathToDirectory + s1);
                                                       ^
/tmp/2037/XMLWriter.java:25: cannot resolve symbol
symbol  : class FileNotFoundException
location: class XMLWriter
          catch(FileNotFoundException filenotfoundexception)
                ^
/tmp/2037/XMLWriter.java:29: cannot resolve symbol
symbol  : class IOException
location: class XMLWriter
          catch(IOException ioexception)
0
Tommy BraasCommented:
I haden't compiled it.

Try this instead:

class XMLWriter
{
      static final char[] OPEN_TAG = {'<','K','E','Y','W','O','R','D','>'};
      static final char[] CLOSE_TAG = {'<','/','K','E','Y','W','O','R','D','>'};
      private static String pathToDirectory = "/Users/tommy/dev/EE/";
      static final byte[] BUFFER = new byte[8192];
      
      public static void writeXML(RandomAccessFile sourceFile) throws IOException
      {
            String s1 = getFileName(sourceFile);
            try
            {
                  FileOutputStream fileoutputstream = new FileOutputStream(pathToDirectory + s1);
                  sourceFile.seek(0);
                  int len = 0;
                  for (long i = 0; i < sourceFile.length(); i += len ) {
                        len = sourceFile.read(BUFFER);
                        if (len > 0) {                              
                              fileoutputstream.write(BUFFER, 0, len);
                        }
                  }
                  fileoutputstream.flush();
                  fileoutputstream.close();
            }
            catch(FileNotFoundException filenotfoundexception)
            {
                  filenotfoundexception.printStackTrace();
            }
            catch(IOException ioexception)
            {
                  ioexception.printStackTrace();
            }
      }
      
      private static String getFileName(RandomAccessFile sourceFile) throws IOException {
            sourceFile.seek(0);
            boolean openTagFound = true;
            long beginIndex = fileIndexOf(sourceFile, OPEN_TAG) + OPEN_TAG.length;
            long endIndex = fileIndexOf(sourceFile, CLOSE_TAG);
            
            if(beginIndex == -1 || endIndex == -1) {
                  return "KeywordNotPresent";
            }

            StringBuffer filename = new StringBuffer();
            sourceFile.seek(beginIndex);
            
            for (long i = beginIndex; i < endIndex; i++ ) {
                  char c = (char) sourceFile.read();
                  filename.append(c);
            }
            String filenameStr = filename.toString();
            return filenameStr;
      }
      

      private static long fileIndexOf(RandomAccessFile sourceFile, final char[] match) throws IOException {
            boolean matchFound = false;
            long matchIndex = -1;
            sourceFile.seek(0);
            for (long i = 0; i < sourceFile.length(); i++ ) {
                  for (int j = 0; j < match.length && i < sourceFile.length(); j++, i++ ) {
                        char c = (char)sourceFile.read();
                        if ( match[j] == c ) {
                              if (matchIndex == -1) {
                                    matchIndex = i;
                              }
                              if (j == match.length - 1) {
                                     matchFound = true;
                              }
                              continue;
                        } else {
                              break;
                        }
                  }
                  if ( matchFound ) {
                        break;
                  }
                  matchIndex = -1;
            }
            if ( !matchFound ) {
                  return -1;
            }
            return matchIndex;
      }
}
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
jsuttorAuthor Commented:
It seemed my problem was the reading of the stream... It was waiting for the stream to finish a file and then trying to read the entire stream to find the file name. Well if the stream was 2mb it was taking about 4 hours to read the stream when it only really needed to search the first 200 characters after the ?xml to find the file name. Once we switched the that a 2mb file took less than 30 seconds to write! Amazing! Thanks for you help orangehead911 .... you helped my friend narrow down the solution.
0
Tommy BraasCommented:
;-D
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.