Java file upload - inputstream issue - java

I have to upload some files from jsp page, when i read the inputstream for the same.
I am checking for its authenticity that its a valid file or not, for that I am using jmimemagic and it takes input stream as argument and now when I am trying to upload it, its only uploading 1 byte of data?
I feel like there is some issue with inputstream any solution pls?
//For checking the file type
InputStream loIns = aoFileStream.getInputStreamToReadFile();
byte[] fileArray = IOUtils.toByteArray(loIns);
mimeType = Magic.getMagicMatch(fileArray, true).getMimeType();
if(!loAllowedFileTypesMimeList.contains(mimeType)){
return false;
}else{
String lsFileName = aoFileStream.getFileName();
String lsFileExt = lsFileName.substring(lsFileName.lastIndexOf(".") + 1);
if(loAllowedFileTypesList.contains(lsFileExt.toLowerCase())){
return true;
}
return false;
}
// For uploading the content
File loOutputFile = new File(asFilePathToUpload);
if(!loOutputFile.exists()){
FileOutputStream loOutput = new FileOutputStream(loOutputFile);
while (liEnd != -1) {
liEnd = inputStreamToReadFile.read();
loOutput.write(liEnd);
}
inputStreamToReadFile.close();
loOutput.close();
}

In
byte[] fileArray = IOUtils.toByteArray(loIns);
you've already exhausted your inputstream, so when you want to write it to a file, you should use the content of the fileArray, not your loIns:
FileUtils.writeByteArrayToFile(loOutput, fileArray);
FileUtils is provided by apache-commons

Related

Large file upload using FileInputStream and FileOutputStream

HttpExchange exchange;
OutputStream responseBody = null;
try{
File fileVal = new File(file);
InputStream inVal = new FileInputStream(fileVal);
exchange.sendResponseHeaders(HTTP_OK, fileVal.length());
responseBody = exchange.getResponseBody();
int read;
byte[] buffer = new byte[4096];
while ((readVal = inVal.read(buffer)) != -1){
responseBody.write(buffer, 0, readVal);
}
} catch (FileNotFoundException e){
//uh-oh, the file doesn't exist
} catch (IOException e){
//uh-oh, there was a problem reading the file or sending the response
} finally {
if (responseBody != null){
responseBody.close();
}
}
I am tring to upload large video file as chunks .while doing the operation I am getting the following error.
groovy.lang.GroovyRuntimeException: Could not find matching constructor for: java.io.File(org.springframework.web.multipart.commons.CommonsMultipartFile)
any anyone guide me to solve this.
File fileVal = new File(file);
Here file is org.springframework.web.multipart.commons.CommonsMultipartFile type and you are trying to create File object by passing CommonsMultipartFile object in constructor and File class does not have constructor of CommonsMultipartFile type.
Check here for File Class Constructor
You Need to get Bytes from file object and create a java.io.File object.
Convert MultiPartFile into File
The error message descripes the failure perfectly. There is no constructor for the class File that accept a parameter of the type org.springframework.web.multipart.commons.CommonsMultipartFile.
Try using the path to the file you want to open. For example:
String path = "/path/to/your/file.txt";
File fileVal = new File(path);
Alternatively you can use the getInputStream() method from CommonsMultipartFile.
InputStream inVal = file.getInputStream();

How to offer download of local PDF file in Java?

I have JBoss running as application server and somewhere on my HD there is a PDF file, that gets created when the user clicks on a specific action. Let's say the file is here: C:/PDF/doonot/10.07.2012/doonot.pdf. How can I offer this file as download? I already did it for a CSV file, but I don't know how to do it with PDF.
Any help is much appreciated.
as i wrote on Is there a common way to download all types of files in jsp?
you can use something like this:
public HttpServletResponse getFile (HttpServletRequest request ,HttpServletResponse httpServletResponse, .......){
HttpServletResponse response = httpServletResponse;
InputStream in =/*HERE YOU READ YOUR FILE AS BinaryStream*/
String filename = "";
String agent = request.getHeader("USER-AGENT");
if (agent != null && agent.indexOf("MSIE") != -1)
{
filename = URLEncoder.encode(/*THIS IS THE FILENAME SHOWN TO THE USER*/, "UTF8");
response.setContentType("application/x-download");
response.setHeader("Content-Disposition","attachment;filename=" + filename);
}
else if ( agent != null && agent.indexOf("Mozilla") != -1)
{
response.setCharacterEncoding("UTF-8");
filename = MimeUtility.encodeText(/*THIS IS THE FILENAME SHOWN TO THE USER*/, "UTF8", "B");
response.setContentType("application/force-download");
response.addHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
}
BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
byte by[] = new byte[32768];
int index = in.read(by, 0, 32768);
while (index != -1) {
out.write(by, 0, index);
index = in.read(by, 0, 32768);
}
out.flush();
return response;
}
UPDATE:
Dont forget that you can use the InputStream as this:
// read local file into InputStream
InputStream inputStream = new FileInputStream("c:\\SOMEFILE.xml");
or you can use it even like this
//read from database
Blob blob = rs.getBlob(1);
InputStream in = blob.getBinaryStream();
You can simply write a servlet wich read the pdf and write it to the response output stream.
Exemple here : http://www.java-forums.org/blogs/servlet/668-how-write-servlet-sends-file-user-download.html
Yes Gustav is right. Java doesn't discriminate amongst file types. A file is a file, if you did it for csv, it should also work for pdf.

Java: PDF converter works in Mac but in Windows, produce empty PDF file

I need a little help here with my PDF converter program.
So, I'm doing this mobile agent PDF converter using JADE framework. But, the problem that I am facing is more related to the way I convert a text file into PDF, send it across network as binary and restore PDF file back.
The program that I've written works properly on my MacBook.
But, on a Windows, it restores my PDF file as an empty PDF.
Here is my code that I use for sending the PDF file across.
private void sendPDF(File f, String recipient) {
String content = "";
if(f != null) {
try {
FileInputStream fis = new FileInputStream(f);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int noBytesRead = 0;
byte[] buffer = new byte[1024];
while((noBytesRead = fis.read(buffer)) != -1) {
baos.write(buffer, 0, noBytesRead);
}
content = baos.toString();
fis.close();
baos.close();
System.out.println("Successful PDF-to-byte conversion.");
} catch (Exception e) {
System.out.println("Exception while converting PDF-to-byte.");
content = "failed";
e.printStackTrace();
}
} else {
System.out.println("PDF-to-file conversion failed.");
content = "failed";
}
ACLMessage message = new ACLMessage(ACLMessage.INFORM);
message.addReceiver(new AID(recipient, AID.ISLOCALNAME));
message.setContent(content);
myAgent.send(message);
System.out.println("PDF document has been sent to requesting client.");
}
And, here is the code that I use to restore the PDF back.
private File restorePDF(String content) {
String dirPDF = dirBuffer + "/" + new Date().getTime() + ".pdf";
File f = new File(dirPDF);
try {
if(!f.exists()) f.createNewFile();
byte[] buffer = new byte[1024];
ByteArrayInputStream bais = new ByteArrayInputStream(content.getBytes());
FileOutputStream fos = new FileOutputStream(f);
int noBytesRead = 0;
while((noBytesRead = bais.read(buffer)) != -1) {
fos.write(buffer, 0, noBytesRead);
}
fos.flush();
fos.close();
bais.close();
} catch (Exception e) {
e.printStackTrace();
f = null;
}
return f;
}
Any help on this would be much appreciated! :)
Question is a little bit confusing, since there is nothing specific about PDF content.
I am supposing you actually want to send bytes, actually send a string, and the string encoding is different on the client and server.
This is usually where troubles happen:
content = baos.toString();
and:
content.getBytes()
A PDF file is a binary file format with lookup tables and lots of binary data blocks to making it a String will break it. If you want to know about the insides of a PDF file, I have written a whole load of blog posts about it (http://www.jpedal.org/PDFblog/2010/09/understanding-the-pdf-file-format-series/)
One issue is that you're using the wrong separator char. Java has a built in function that will return the correct char for the correct os. See separator char.
Your code will look something like this
String dirPDF = dirBuffer + File.separatorChar + new Date().getTime() + ".pdf";
For reference:
separatorChar
The system-dependent default name-separator character. This field is
initialized to contain the first character of the value of the system
property file.separator. On UNIX systems the value of this field is
'/'; on Microsoft Windows systems it is '\'.

How to use java.util.zip to archive/deflate string in java for use in Google Earth?

Use Case
I need to package up our kml which is in a String into a kmz response for a network link in Google Earth. I would like to also wrap up icons and such while I'm at it.
Problem
Using the implementation below I receive errors from both WinZip and Google Earth that the archive is corrupted or that the file cannot be opened respectively. The part that deviates from other examples I'd built this from are the lines where the string is added:
ZipEntry kmlZipEntry = new ZipEntry("doc.kml");
out.putNextEntry(kmlZipEntry);
out.write(kml.getBytes("UTF-8"));
Please point me in the right direction to correctly write the string so that it is in doc.xml in the resulting kmz file. I know how to write the string to a temporary file, but I would very much like to keep the operation in memory for understandability and efficiency.
private static final int BUFFER = 2048;
private static void kmz(OutputStream os, String kml)
{
try{
BufferedInputStream origin = null;
ZipOutputStream out = new ZipOutputStream(os);
out.setMethod(ZipOutputStream.DEFLATED);
byte data[] = new byte[BUFFER];
File f = new File("./icons"); //folder containing icons and such
String files[] = f.list();
if(files != null)
{
for (String file: files) {
LOGGER.info("Adding to KMZ: "+ file);
FileInputStream fi = new FileInputStream(file);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(file);
out.putNextEntry(entry);
int count;
while((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
origin.close();
}
}
ZipEntry kmlZipEntry = new ZipEntry("doc.kml");
out.putNextEntry(kmlZipEntry);
out.write(kml.getBytes("UTF-8"));
}
catch(Exception e)
{
LOGGER.error("Problem creating kmz file", e);
}
}
Bonus points for showing me how to put the supplementary files from the icons folder into a similar folder within the archive as opposed to at the same layer as the doc.kml.
Update Even when saving the string to a temp file the errors occur. Ugh.
Use Case Note The use case is for use in a web app, but the code to get the list of files won't work there. For details see how-to-access-local-files-on-server-in-jboss-application
You forgot to call close() on ZipOutputStream. Best place to call it is the finally block of the try block where it's been created.
Update: To create a folder, just prepend its name in the entry name.
ZipEntry entry = new ZipEntry("icons/" + file);

Convert audio stream to WAV byte array in Java without temp file

Given an InputStream called in which contains audio data in a compressed format (such as MP3 or OGG), I wish to create a byte array containing a WAV conversion of the input data. Unfortunately, if you try to do this, JavaSound hands you the following error:
java.io.IOException: stream length not specified
I managed to get it to work by writing the wav to a temporary file, then reading it back in, as shown below:
AudioInputStream source = AudioSystem.getAudioInputStream(new BufferedInputStream(in, 1024));
AudioInputStream pcm = AudioSystem.getAudioInputStream(AudioFormat.Encoding.PCM_SIGNED, source);
AudioInputStream ulaw = AudioSystem.getAudioInputStream(AudioFormat.Encoding.ULAW, pcm);
File tempFile = File.createTempFile("wav", "tmp");
AudioSystem.write(ulaw, AudioFileFormat.Type.WAVE, tempFile);
// The fileToByteArray() method reads the file
// into a byte array; omitted for brevity
byte[] bytes = fileToByteArray(tempFile);
tempFile.delete();
return bytes;
This is obviously less desirable. Is there a better way?
The problem is that the most AudioFileWriters need to know the file size in advance if writing to an OutputStream. Because you can't provide this, it always fails. Unfortunatly, the default Java sound API implementation doesn't have any alternatives.
But you can try using the AudioOutputStream architecture from the Tritonus plugins (Tritonus is an open source implementation of the Java sound API): http://tritonus.org/plugins.html
I notice this one was asked very long time ago. In case any new person (using Java 7 and above) found this thread, note there is a better new way doing it via Files.readAllBytes API. See:
How to convert .wav file into byte array?
Too late, I know, but I was needed this, so this is my two cents on the topic.
public void UploadFiles(String fileName, byte[] bFile)
{
String uploadedFileLocation = "c:\\";
AudioInputStream source;
AudioInputStream pcm;
InputStream b_in = new ByteArrayInputStream(bFile);
source = AudioSystem.getAudioInputStream(new BufferedInputStream(b_in));
pcm = AudioSystem.getAudioInputStream(AudioFormat.Encoding.PCM_SIGNED, source);
File newFile = new File(uploadedFileLocation + fileName);
AudioSystem.write(pcm, Type.WAVE, newFile);
source.close();
pcm.close();
}
The issue is easy to solve if you prepare class which will create correct header for you. In my example Example how to read audio input in wav buffer data goes in some buffer, after that I create header and have wav file in the buffer. No need in additional libraries. Just copy the code from my example.
Example how to use class which creates correct header in the buffer array:
public void run() {
try {
writer = new NewWaveWriter(44100);
byte[]buffer = new byte[256];
int res = 0;
while((res = m_audioInputStream.read(buffer)) > 0) {
writer.write(buffer, 0, res);
}
} catch (IOException e) {
System.out.println("Error: " + e.getMessage());
}
}
public byte[]getResult() throws IOException {
return writer.getByteBuffer();
}
And class NewWaveWriter you can find under my link.
This is very simple...
File f = new File(exportFileName+".tmp");
File f2 = new File(exportFileName);
long l = f.length();
FileInputStream fi = new FileInputStream(f);
AudioInputStream ai = new AudioInputStream(fi,mainFormat,l/4);
AudioSystem.write(ai, Type.WAVE, f2);
fi.close();
f.delete();
The .tmp file is a RAW audio file, the result is a WAV file with header.

Categories