7 Replies Latest reply on Aug 20, 2010 10:21 AM by karlh

    fileUpload blowing heap

    karlh

      Hi,
      I am using the fileUpload control to upload large files to an application server, and store the files.


      I have turned on the multipart filter and the create-temp-files flag.


             <web:multipart-filter create-temp-files="true" 
                                max-request-size="2147483646"
                                url-pattern="*.seam"/>
      


      This works fine. I can see that when a file is in the process of being uploaded, it is written to /tmp (on linux) and grows until complete. However, when I then try to store the file, (effectively I guess reading the whole thing into memory) it blows the heap unless I make the heap big enough to handle the largest file + whatever jboss needs.


      <s:fileUpload id="importFileUploader"
      data="#{FileUploadController.uploadFileContents}"
      maxlength="255"
      fileSize="#{FileUploadController.uploadFileSize}"
      fileName="#{FileUploadController.uploadFileName}"
      disabled="false" size="49" accept="*"
      contentType="#{FileUploadController.uploadContentType}"
      required="true"/>
      



      My backing bean has the following methods:


             public byte[] getUploadFileContents() {
                      return uploadFileContents;
              }
      
              public void setUploadFileContents(byte[] data) {
                      this.uploadFileContents = data;
              }



      I know one solution is to increase the heap size, but as I do not want to parse the files, and have no need to read them into memory in full, is there another way to access what I have uploaded? I know the complete file is there in the /tmp directory, but just do not know how to tie this in to my backing bean so I can use it without reading everything in a byte array.


      Thanks,
      Karlh.

        • 1. Re: fileUpload blowing heap
          cash1981

          What do you want to accomplish exactly?


          Do you want to store the file in DB? Do you want to serve the file to the user?

          • 2. Re: fileUpload blowing heap
            karlh

            What I want to accomplish is:


            Users remote to the application server can upload a file from their local machine to the machine where the app server is. There are other processes running on the machine, which will further process the uploaded files once they are placed in a well known dir with a particular file name pattern.


            At the moment I can do this, it works fine (unless the file is so big it blows the heap), but I could not help but notice that the file is getting uploaded to /tmp as part of the fileUpload processing, and was wondering is there a way I can use this feature (the temp-file creation) to avoid reading the contents of the file (which I do not care about) into memory?

            • 3. Re: fileUpload blowing heap
              cash1981

              Let me see if I understand you (because you basically just wrote what you originally said in your question).


              You want to read a file, but not read it in memory first? Like reading XML by using SAX which reads it line by line and not DOM which loads the entire file in memory?
              If this is what you want to accomplish, then it depends on what kind of InputStream you are using, and how you are reading the file (ie byte for byte). (But something tells me you didn't ask for this)

              • 4. Re: fileUpload blowing heap
                karlh

                I dont really want to read the file, but as far as I can see, I have to read it using the fileUpload control. At the moment, from my original post, you can see that my backing bean has a getter and setter with byte[] for the file contents. This type of backing bean method was the only example I could find. Like your analogy to a DOM versus SAX parser, I am currently using the DOM method, as the whole file is being passed as a byte array. I would like to have the equivalent of SAX.


                Is there another way?

                • 5. Re: fileUpload blowing heap
                  amitev

                  I think this is possible using temp file and InputStream. The data attribute accepts value expression pointing to a reference of type InputStream. This is from the seam docs:


                  data — this value binding receives the binary file data. 
                  The receiving field should be declared as a byte[] or InputStream (required). 
                  



                  So if you read the input stream and store it somewhere else without capturing the whole data in the memory.

                  • 6. Re: fileUpload blowing heap
                    karlh

                    Thanks,
                    I will play around with that method and see what the results are. I could not find any InputStream examples out there when I started.

                    • 7. Re: fileUpload blowing heap
                      karlh

                      To Follow up, the InputStream method worked fine.


                      Thanks!