rename file after file upload - java

public void handleFileUpload(FileUploadEvent event) {
ExternalContext extContext = FacesContext.getCurrentInstance().getExternalContext();
File result = new File(extContext.getRealPath("//admin//images") + "//" + event.getFile().getFileName());
// File result = new File("D:\\Netbeans Project\\mcGrawLibPro\\mcGrawLibPro-war\\web\\item", event.getFile().getFileName());
File bg = new File(extContext.getRealPath("//admin//images")+"//macback.png");
try {
bg.renameTo(new File(extContext.getRealPath("//admin//images")+"//bg.png"));
File f1 = new File(extContext.getRealPath("//admin//images") + "//macback.png" );
result.renameTo(f1);
//System.out.println(f1);
System.out.println(result);
FileOutputStream fileOutputStream = new FileOutputStream(result);
byte[] buffer = new byte[BUFFER_SIZE];
int bulk;
InputStream inputStream = event.getFile().getInputstream();
while (true) {
bulk = inputStream.read(buffer);
if (bulk < 0) {
break;
}
fileOutputStream.write(buffer, 0, bulk);
fileOutputStream.flush();
}
fileOutputStream.close();
inputStream.close();
FacesMessage msg = new FacesMessage("OK",
event.getFile().getFileName() + " was upload.");
FacesContext.getCurrentInstance().addMessage(null, msg);
} catch (IOException e) {
e.printStackTrace();
FacesMessage error = new FacesMessage("Can't upload!");
FacesContext.getCurrentInstance().addMessage(null, error);
}
}
my problem is when i upload a picture type png such as aaa.png, it can upload on server but it not rename, after upload aaa.png and i re-upload this picture(aaa.png) it can change name but it have 2 file one is aaa.png and one is macback.png
What's wrong in my code?
Thank you !

Here's what I think you are trying to do:
When you upload a file, you want to call it macback.png, not its original file name.
When you upload a second file, you want to rename macback.png to bg.png first, then save the uploaded file as macback.png.
If that is the case, first you need to test for the existence of the macback.png file and rename it if it exists. Then you create a File object for the macback.png file and open a FileOutputStream to that file to write the uploaded file to.
Something like this:
public void handleFileUpload(FileUploadEvent event) {
ExternalContext extContext = FacesContext.getCurrentInstance().getExternalContext();
File result = new File(extContext.getRealPath("//admin//images") + "//macback.png");
if(result.exists()) {
result.renameTo(new File(extContext.getRealPath("//admin//images")+"//bg.png"));
}
try {
File targetFile = new File(extContext.getRealPath("//admin//images") + "//macback.png" );
FileOutputStream fileOutputStream = new FileOutputStream(targetFile);
byte[] buffer = new byte[BUFFER_SIZE];
int bulk;
InputStream inputStream = event.getFile().getInputstream();
while (true) {
bulk = inputStream.read(buffer);
if (bulk < 0) {
break;
}
fileOutputStream.write(buffer, 0, bulk);
fileOutputStream.flush();
}
fileOutputStream.close();
inputStream.close();
FacesMessage msg = new FacesMessage("OK",
event.getFile().getFileName() + " was upload.");
FacesContext.getCurrentInstance().addMessage(null, msg);
} catch (IOException e) {
e.printStackTrace();
FacesMessage error = new FacesMessage("Can't upload!");
FacesContext.getCurrentInstance().addMessage(null, error);
}
}

Ok, so let's see if I got it this time:
You want the first A.png to save as A.png.
The second time A.png is uploaded, you want the first A.png to be renamed to macback.png and the second A.png to be stored as A.png.
If that's the case, try this:
public void handleFileUpload(FileUploadEvent event) {
ExternalContext extContext = FacesContext.getCurrentInstance().getExternalContext();
File result = new File(extContext.getRealPath("//admin//images") + "//" + event.getFile().getFileName());
if(result.exists()) {
result.renameTo(new File(extContext.getRealPath("//admin//images")+"//mackback.png"));
}
try {
File targetFile = new File(extContext.getRealPath("//admin//images") + "//" + event.getFile().getFileName() );
FileOutputStream fileOutputStream = new FileOutputStream(targetFile);
byte[] buffer = new byte[BUFFER_SIZE];
int bulk;
InputStream inputStream = event.getFile().getInputstream();
while (true) {
bulk = inputStream.read(buffer);
if (bulk < 0) {
break;
}
fileOutputStream.write(buffer, 0, bulk);
fileOutputStream.flush();
}
fileOutputStream.close();
inputStream.close();
FacesMessage msg = new FacesMessage("OK",
event.getFile().getFileName() + " was upload.");
FacesContext.getCurrentInstance().addMessage(null, msg);
} catch (IOException e) {
e.printStackTrace();
FacesMessage error = new FacesMessage("Can't upload!");
FacesContext.getCurrentInstance().addMessage(null, error);
}
}

I believe the issue is you are trying to rename result to f1 too early. At the point where you are calling result.renameTo(f1) you have not yet created the file referenced by result so the rename has no effect. You cannot rename a file before it exists on disk.
Now, you don't really need to rename result. Since you have not created the file, you can simply use f1 as the argument to FileOutputStream instead of result.

Related

Creating a download for zip file containing text/csv from string variables

I currently need to create a zip file for downloading. This should contain two (2) csv files that are to be created from string variables. I'm at a loss on how I should do this. My draft is below.
public #ResponseBody Object getFileV1(HttpServletRequest request, HttpServletResponse response) {
try {
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=Reassigned Tickets Report " + new Date().toString() + ".zip");
String stringValue1 = "This is a test value for csv1";
String stringValue2 = "This is a test value for csv2";
InputStream is1 = new ByteArrayInputStream(stringValue1.getBytes("UTF-8"));
InputStream is2 = new ByteArrayInputStream(stringValue2.getBytes("UTF-8"));
ZipInputStream zin;
ZipEntry entry;
ZipOutputStream zout= new ZipOutputStream(response.getOutputStream());
zin = new ZipInputStream(is1);
entry = zin.getNextEntry();
zout.putNextEntry(entry);
zin = new ZipInputStream(is2);
entry = zin.getNextEntry();
zout.putNextEntry(entry);
zout.closeEntry();
zin.close();
zout.close();
response.flushBuffer();
return null;
} catch (Exception e) {
e.printStackTrace();
return e;
}
}
Obviously this is not working. Probably because I'm still a novice at this. Please bear with me.
I get a "java.lang.NullPointerException" at the line where "zout.putNextEntry" is called. Would appreciate your advice. Thank you in advance.
I solved my problem after a day of looking around. This works for me. But I'm not sure if this is the most efficient way.
public #ResponseBody Object getFileV1(HttpServletRequest request, HttpServletResponse response) {
try {
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=Test Report " + new Date().toString() + ".zip");
String stringValue1 = "This is a test value for csv1";
String stringValue2 = "This is a test value for csv2";
PrintWriter writer1 = new PrintWriter(new OutputStreamWriter(new FileOutputStream("stringValue1.csv"), "UTF-8"));
writer1.print(stringValue1);
writer1.close();
PrintWriter writer2 = new PrintWriter(new OutputStreamWriter(new FileOutputStream("stringValue2.csv"), "UTF-8"));
writer2.print(stringValue2);
writer2.close();
File file1 = new File("stringValue1.csv");
File file2 = new File("stringValue2.csv");
filesToZip(response, file1, file2);
file1.delete();
file2.delete();
response.flushBuffer();
return null;
} catch (Exception e) {
e.printStackTrace();
return e;
}
}
This is the method I got from another thread with a few edits.
public static void filesToZip(HttpServletResponse response, File... files) throws IOException {
// Create a buffer for reading the files
byte[] buf = new byte[1024];
// create the ZIP file
ZipOutputStream out = new ZipOutputStream(response.getOutputStream());
// compress the files
for(int i=0; i<files.length; i++) {
FileInputStream in = new FileInputStream(files[i].getName());
// add ZIP entry to output stream
out.putNextEntry(new ZipEntry(files[i].getName()));
// transfer bytes from the file to the ZIP file
int len;
while((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
// complete the entry
out.closeEntry();
in.close();
}
// complete the ZIP file
out.close();
}
The only thing I don't love is that I had to create temporary files and delete them after processing.

Download dynamically created zip files in play framework

Hi i am trying to write a play framework service where i can download multiple files. I create zip of multiple file on the fly but i am not sure how to send it as a response in Play Framework i will show what i have done so far.
public Result download() {
String[] items = request().queryString().get("items[]");
String toFilename = request().getQueryString("toFilename");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(baos))) {
for (String item : items) {
Path path = Paths.get(REPOSITORY_BASE_PATH, item);
if (Files.exists(path)) {
ZipEntry zipEntry = new ZipEntry(path.getFileName().toString());
zos.putNextEntry(zipEntry);
byte buffer[] = new byte[2048];
try (BufferedInputStream bis = new BufferedInputStream(Files.newInputStream(path))) {
int bytesRead = 0;
while ((bytesRead = bis.read(buffer)) != -1) {
zos.write(buffer, 0, bytesRead);
}
} finally {
zos.closeEntry();
}
}
}
response().setHeader("Content-Type", "application/zip");
response().setHeader("Content-Disposition", "inline; filename=\"" + MimeUtility.encodeWord(toFilename) + "\"");
//I am confused here how to output the response of zip file i have created
//I tried with the `baos` and with `zos` streams but not working
return ok(baos.toByteArray());
} catch (IOException e) {
LOG.error("copy:" + e.getMessage(), e);
return ok(error(e.getMessage()).toJSONString());
}
return null;
}
i tried sending response with return ok(baos.toByteArray()); i was able to download file but when i open the downloaded file it give me error An error occurred while loading the archive.
You need to close the zip file. After adding all entries, do: zos.close()
On a side note, I would recommend writing the zip file to disk rather than keeping it in a memory buffer. You could then use return ok(File content, String filename) to send its content to the client.
I am adding this answer if someone wants to know what was the final code:
String[] items = request().queryString().get("items[]");
String toFilename = request().getQueryString("toFilename");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(baos))) {
for (String item : items) {
Path path = Paths.get(REPOSITORY_BASE_PATH, item);
if (Files.exists(path)) {
ZipEntry zipEntry = new ZipEntry(path.getFileName().toString());
zos.putNextEntry(zipEntry);
byte buffer[] = new byte[2048];
try (BufferedInputStream bis = new BufferedInputStream(Files.newInputStream(path))) {
int bytesRead = 0;
while ((bytesRead = bis.read(buffer)) != -1) {
zos.write(buffer, 0, bytesRead);
}
} finally {
zos.closeEntry();
}
}
}
zos.close(); //closing the Zip
response().setHeader("Content-Type", "application/zip");
response().setHeader("Content-Disposition", "attachment; filename=\"" + MimeUtility.encodeWord(toFilename) + "\"");
return ok(baos.toByteArray());
} catch (IOException e) {
LOG.error("copy:" + e.getMessage(), e);
return ok(error(e.getMessage()).toJSONString());
}
Thank you for the help! There are two extra changes I made so it works for me in scala playframework 2.5.x
instead of return ok(baos.toByteArray()) ,
use Ok.chunked(StreamConverters.fromInputStream(fileByteData))
Instead of reading byte to byte the file,FileUtils.readFileToByteArray(file) can be very helpful here.
Attached is the complete version of my code.
import java.io.{BufferedOutputStream, ByteArrayInputStream, ByteArrayOutputStream}
import java.util.zip.{ZipEntry, ZipOutputStream}
import akka.stream.scaladsl.{StreamConverters}
import org.apache.commons.io.FileUtils
import play.api.mvc.{Action, Controller}
class HomeController extends Controller {
def single() = Action {
Ok.sendFile(
content = new java.io.File("C:\\Users\\a.csv"),
fileName = _ => "a.csv"
)
}
def zip() = Action {
Ok.chunked(StreamConverters.fromInputStream(fileByteData)).withHeaders(
CONTENT_TYPE -> "application/zip",
CONTENT_DISPOSITION -> s"attachment; filename = test.zip"
)
}
def fileByteData(): ByteArrayInputStream = {
val fileList = List(
new java.io.File("C:\\Users\\a.csv"),
new java.io.File("C:\\Users\\b.csv")
)
val baos = new ByteArrayOutputStream()
val zos = new ZipOutputStream(new BufferedOutputStream(baos))
try {
fileList.map(file => {
zos.putNextEntry(new ZipEntry(file.toPath.getFileName.toString))
zos.write(FileUtils.readFileToByteArray(file))
zos.closeEntry()
})
} finally {
zos.close()
}
new ByteArrayInputStream(baos.toByteArray)
}
}

android ZipArchiveEntry giving java.nio.charset.MalformedInputException

I can unzip the 1st and 2nd entry of a zip file I am reading from the web, but then I get the MalformedInputException error. The zip file consists of unicode file names of mp3 files. I created the zip file that I placed on the web using Winzip (I tried both v11 and V18).
The mp3 files are all at the 'root' level in the zip file, i.e. not stored in subfolders.
I tried first with ZipInputStream. The last attempt (below) is with ArchiveInputStream. (I noticed that ArchiveInputStream didn't have a closeEntry() method like ZipInputStream - not that it made any difference).
The error always occurs on the line that gets the next entry.
while ((entry = (ZipArchiveEntry)zipStream.getNextEntry()) != null)
The code is
private void unizpMediaFile(String mediaDirectory, String zipFileURL) {
InputStream inputStream = null;
ArchiveInputStream zipStream = null;
ArchiveEntry entry = null;
try {
// make sure can write to (probably) sd card
File mediaFileDirectory = createMediaDirectory(mediaDirectory);
if (mediaFileDirectory == null)
return;
inputStream = getHttpInputStream(zipFileURL);
if (inputStream == null) {
return;
}
zipStream = new ArchiveStreamFactory().createArchiveInputStream(ArchiveStreamFactory.ZIP,new BufferedInputStream(
inputStream) );
while ((entry = (ZipArchiveEntry)zipStream.getNextEntry()) != null) {
Log.i(TAG,"Entry:" + entry.getName());
if (entry.isDirectory()) {
if (false == new File( mediaFileDirectory.getAbsoluteFile()
+ File.separator + entry.getName()).mkdirs()) {
return;
}
} else {
OutputStream out = new FileOutputStream(mediaFileDirectory.getAbsoluteFile()
+ File.separator + entry.getName());
int size;
byte[] buffer = new byte[4096];
FileOutputStream outStream = new FileOutputStream(
mediaFileDirectory.getAbsoluteFile()
+ File.separator + entry.getName());
BufferedOutputStream bufferOut = new BufferedOutputStream(
outStream, buffer.length);
while ((size = zipStream.read(buffer, 0, buffer.length)) != -1) {
bufferOut.write(buffer, 0, size);
}
bufferOut.flush();
bufferOut.close();
out.close();
Log.i(TAG,"Entry:" + entry.getName() + " closed.");
}
}
maintOpDetails.append(res.getString(R.string.load_complete));
updateLoadDetails(maintOpDetails.toString() );
} catch (FileNotFoundException e) {
Log.e(TAG, "unizpMediaFile" + e.toString());
storeErrorMessage(res.getString(R.string.error_reading_media_zip_file,
zipFileURL, e.toString()));
} catch (IOException e) {
Log.e(TAG, "unizpMediaFile" + e.toString());
storeErrorMessage(res.getString(R.string.error_reading_media_zip_file,
zipFileURL, e.toString()));
} catch (ArchiveException e) {
Log.e(TAG, "unizpMediaFile" + e.toString());
storeErrorMessage(res.getString(R.string.error_reading_media_zip_file,
zipFileURL, e.toString()));
}
finally {
if (inputStream != null){ try {inputStream.close();} catch (Exception e){} }
if (zipStream != null){ try {zipStream.close();} catch (Exception e){} }
}
}
private InputStream getHttpInputStream(String url) {
HttpResponse response;
InputStream is = null;
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httppost = new HttpGet("http://" + url);
try {
response = httpClient.execute(httppost);
HttpEntity ht = response.getEntity();
BufferedHttpEntity buf;
buf = new BufferedHttpEntity(ht);
is = buf.getContent();
} catch (ClientProtocolException e) {
Log.e(TAG, "getHttpInputStream" + e.toString());
storeErrorMessage(res.getString(R.string.error_reading_file_at_url,
url, e.toString()));
} catch (ConnectTimeoutException cte) {
Log.e(TAG, "getHttpInputStream" + cte.toString());
storeErrorMessage(res.getString(R.string.connect_timetout_error, url));
} catch (IOException e) {
Log.e(TAG, "getHttpInputStream" + e.toString());
storeErrorMessage(res.getString(R.string.error_reading_file_at_url,
url, e.toString()));
}
return is;
}
From the log I get
I/LoadLanguageLessonService(3102): Entry:evet.mp3
I/LoadLanguageLessonService(3102): Entry:evet.mp3 closed.
I/LoadLanguageLessonService(3102): Entry:hay?r.mp3
I/LoadLanguageLessonService(3102): Entry:hay?r.mp3 closed.
E/LoadLanguageLessonService(3102): unizpMediaFilejava.nio.charset.MalformedInputException: Length: 1
(The cut/paste from the log to here caused the unicode filename values to be converted to the '?' you see above.)
I checked out various SO postings with no luck.
Any ideas?
Some followup
I modified my code to first download the zip file to my phone and then unzip it from there. No luck doing it that way either.
I also used the following code
ZipFile zipFile = null;
try {
zipFile = new ZipFile(zipFilename);
Enumeration<?> enu = zipFile.entries();
while (enu.hasMoreElements()) {
ZipEntry zipEntry = (ZipEntry) enu.nextElement();
String name = zipEntry.getName();
long size = zipEntry.getSize();
long compressedSize = zipEntry.getCompressedSize();
Log.e(TAG, String.format("name: %-20s | size: %6d | compressed size: %6d\n",
name, size, compressedSize));
}
} catch (IOException e) {
e.printStackTrace();
throw e;
}
to list all the entries in the zip file and found that the unicode characters all show up as a small black diamond with a question mark inside (after cut/paste into SO the characters show up just with the ? mark).
I also downloaded AndroZip and WinZip for Android and viewed the zip file via both apps on my phone. Again the unicode file names were corrupted.
At this point I am stuck. I think I will shift gears and see about downloading the files one by one.

How to convert MultipartFile into byte stream

//Or any other solution to saving multipartfile into DB.
I tried with this way but getting error.
File fileOne = new File("file.getOrignalFileName");//what should be kept inside this method
byte[] bFile = new byte[(int) fileOne.length()];
try {
FileInputStream fileInputStream = new FileInputStream(fileOne);
//convert file into array of bytes
fileInputStream.read(bFile);
fileInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
questionDao.saveImage(bFile);
MultipartFile file;
byte [] byteArr=file.getBytes();
InputStream inputStream = new ByteArrayInputStream(byteArr);
//Start Photo Upload with Adhaar No//
if (simpleLoanDto.getPic() != null && simpleLoanDto.getAdharNo() != null) {
String ServerDirPath = globalVeriables.getAPath() + "\\";
File ServerDir = new File(ServerDirPath);
if (!ServerDir.exists()) {
ServerDir.mkdirs();
}
// Giving File operation permission for LINUX//
IOperation.setFileFolderPermission(ServerDirPath);
MultipartFile originalPic = simpleLoanDto.getPic();
byte[] ImageInByte = originalPic.getBytes();
FileOutputStream fosFor = new FileOutputStream(
new File(ServerDirPath + "\\" + simpleLoanDto.getAdharNo() + "_"+simpleLoanDto.getApplicantName()+"_.jpg"));
fosFor.write(ImageInByte);
fosFor.close();
}
//End Photo Upload with Adhaar No//

Uploading binary files using dropbox java api

Could you point me out to a code or url where I can find some examples how to use dropbox java api and upload binary files like, .doc files jpg and video files.
Current examples in the web only point to uploading a text file. But when I try to read files using java InputStream and convert them to byte array and pass into dropbox file upload functions files get corrupted. Same issue with downloading files as well. Thanks in Advance.
Regards,
Waruna.
EDIT--
Code Sample
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte [] buf = new byte[1024];
for(int readNum; (readNum = fis.read(buf)) != -1;) {
bos.write(buf, 0, readNum);
System.out.println("read "+ readNum + "bytes,");
}
ByteArrayInputStream inputStream2 = new ByteArrayInputStream(bos.toByteArray());
Entry newEntry = mDBApi.putFile("/uploads/"+file.getName(), inputStream2, file.toString().length(), null, null);
System.out.println("Done. \nRevision of file: " + newEntry.rev + " " + newEntry.mimeType);
return newEntry.rev;
The 3rd argument of DropboxAPI.putFile() should be the number of bytes to read from the input stream - You are passing the length of the filename.
Instead of
Entry newEntry = mDBApi.putFile("/uploads/"+file.getName(), inputStream2,
file.toString().length(), null, null);
Use
Entry newEntry = mDBApi.putFile("/uploads/"+file.getName(), inputStream2,
bos.size(), null, null);
I don't think you need to convert to byte array, simply use FileInputStream is enough for a file, txt as well as binary. The following code works, I just tested with JPG.
DropboxAPI<?> client = new DropboxAPI<WebAuthSession>(session);
FileInputStream inputStream = null;
try {
File file = new File("some_pic.jpg");
inputStream = new FileInputStream(file);
DropboxAPI.Entry newEntry = client.putFile("/testing.jpg", inputStream,
file.length(), null, null);
System.out.println("The uploaded file's rev is: " + newEntry.rev);
} catch (DropboxUnlinkedException e) {
// User has unlinked, ask them to link again here.
System.out.println("User has unlinked.");
} catch (DropboxException e) {
System.out.println("Something went wrong while uploading.");
} catch (FileNotFoundException e) {
System.out.println("File not found.");
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {}
}
}

Categories