Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Uploading non-ascii (pdf/jpeg) files w/ servlets + <insert type="file&qu

Status
Not open for further replies.

pr0n603

Programmer
Dec 14, 2004
23
0
0
US
hi,

I am writting a servlet that reads the uploaded file from InputStream data from the HttpServletRequest and write a file of that type to the server. I saw sedj's code on The jsp code works w/o a glitch for ASCII files like with .txt extension but non-ascii files (pdf/doc/jpeg) become corrupt

I wanted to know why that was the case and how i could change the code so that it works for other types files. (The file seems to be the right size and everything, but for somereason, somethign causes it to be corrupt)

Thank you very very very much for your help!!

the servlet code (taken from sedj's post) is:
Code:
String contentType = request.getContentType();
    System.out.println("Content type is :: " +contentType);
    if ((contentType != null) && (contentType.indexOf("multipart/form-data") >= 0)) {
        DataInputStream in = new DataInputStream(request.getInputStream());
        int formDataLength = request.getContentLength();

        byte dataBytes[] = new byte[formDataLength];
        int byteRead = 0;
        int totalBytesRead = 0;
        while (totalBytesRead < formDataLength) {
            byteRead = in.read(dataBytes, totalBytesRead, formDataLength);
            totalBytesRead += byteRead;
        }

        String file = new String(dataBytes);
        String saveFile = file.substring(file.indexOf("filename=\"") + 10);
        saveFile = saveFile.substring(0, saveFile.indexOf("\n"));
        saveFile = saveFile.substring(saveFile.lastIndexOf("\\") + 1,saveFile.indexOf("\""));

        int lastIndex = contentType.lastIndexOf("=");
        String boundary = contentType.substring(lastIndex + 1,contentType.length());

        int pos;
        pos = file.indexOf("filename=\"");
        pos = file.indexOf("\n", pos) + 1;
        pos = file.indexOf("\n", pos) + 1;
        pos = file.indexOf("\n", pos) + 1;

        int boundaryLocation = file.indexOf(boundary, pos) - 4;
        int startPos = ((file.substring(0, pos)).getBytes()).length;
        int endPos = ((file.substring(0, boundaryLocation)).getBytes()).length;

        FileOutputStream fileOut = new FileOutputStream(saveFile);
        //fileOut.write(dataBytes);
        fileOut.write(dataBytes, startPos, (endPos - startPos));
        fileOut.flush();
        fileOut.close();
        
        out.println("File saved as " +saveFile);
    }
 
Ok,

Iv figured this out. Sedj's code was right after all. My new problem is getting it to process the data faster. I timed the different sectionsof the code and see that for a large file (12 MB), it takes about 7 seconds to convert the Byte array to a String as in:

String file = new String(dataBytes);

and another 7 or so seconds to get the end position of the actual file data:

int endPos = ((file.substring(0, boundaryLocation)).getBytes()).length;

Im wondering if its possible to cut down on this time and how that can be done. Maybe use a BufferedInputStream? Anyone have any suggestions?

Thanks again!
 
There is only one main thing (that I can see) you can do to speed that example up, though it is obviously a little more tricky.

BufferedInputStream will not help - the IO socket streams are generally buffered on the OS level anyway ... when you do :
byteRead = in.read(dataBytes, totalBytesRead, formDataLength);
This is in effect requesting reading the whole stream at one chunk - and if this chunk is bigger than the server will send in one go, the DataInputStream will basically buffer it for you ...

The reason the example does this :
String file = new String(dataBytes);
is because it makes it easy to rip out the "header" type info (ie the "filename=" stuff before the data. However, reserving 12Mb in memory for this operation is obviously a little costly. So the other way is to rip through the byte[] by hand in a for loop, noting the correct place(index) to start saving the "actual" data. Obviously when you have the index point, exit the loop so you don't loop the whole array.

Hope this makes sense !


--------------------------------------------------
Free Database Connection Pooling Software
 
Im having the same problem when I deployed my web application to a unix os and tried to upload a nontext file I got the following error out of boundary. can anyone help me solve it
 
tarawfp,

What was the exact error? My mistake was that I was using a Reader instead of a Stream so i was reading characters and not bytes and thats why it worked for ASCII files and not binary ones.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top