my thread will read the class data from a jar file, another thread will modify or delete the jar file. the order is read first then delete, but it didn't work, seem that cann't release the resource after reading, how could I reach out?
InputStream is = null;
BufferedInputStream bis = null;
ByteArrayOutputStream baos = null;
try {
URL res = new URL(**file**);
is = res.openStream();
bis = new BufferedInputStream(is);
baos = new ByteArrayOutputStream();
byte[] bytes = new byte[1024 * 10];
int readBytes;
while ((readBytes = bis.read(bytes)) != -1) {
baos.write(bytes, 0, readBytes);
}
byte[] b = baos.toByteArray();
baos.close();
bis.close();
is.close();
return b;
} catch (Exception ex) {
throw ex;
}
the parameter "file" is a String like this "jar:file:///C:/Users/HJ16748/Desktop/test.jar!/com/services/plugin/test/Test.class"
Add a finally to your try catch block and close the resources there. Let two threads name be Read and Modify.
Inside Modify thread before deleting or modifying jar add line like this.
try{
System.out.println("Waiting for read to finish");
read.thread.join();
}catch(InterruptedException e){
System.out.println("not able to join");//oops catch
}
//codes to delete or modify jar
thread called with read is the Thread object
ZipFile zf = new ZipFile(entry);
file = file.replaceAll("\\\\", "/");
ZipEntry zipEntry = zf.getEntry(file);
BufferedInputStream bis = new BufferedInputStream(zf.getInputStream(zipEntry));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] bytes = new byte[1024 * 10];
int readBytes;
while ((readBytes = bis.read(bytes)) != -1) {
baos.write(bytes, 0, readBytes);
}
b = baos.toByteArray();
baos.close();
bis.close();
zf.close();
Related
I want to download multiple files in single zip file using java servlet. I successfully downloaded the zip file containing multiple files (in my web page). but the problem is that files are also downloaded in my server(for ex in my jboss bin folder).
Code:
public void createZipFile(String fileNames,HttpServletResponse response,HttpServletRequest request) {
try {
ZipOutputStream outStream1 = null;
ServletOutputStream outStream=null;
FileInputStream inStream =null;
FileOutputStream fos=null;
InputStream inputStream =null;
int bytesRead = 0;
String zipFileName = "zipFileName.zip";
response.setHeader("Content-Disposition", "attachment;filename=\""+zipFileName+"\"");
response.setHeader("Pragma", "private");
response.addHeader("Cache-Control", "no-transform, max-age=0");
response.setHeader("Accept-Ranges", "bytes");
response.setContentType("application/zip");
//fileNames contains multiple file name.so i want to split and get each file
String[] fileName = fileNames.split(",");
byte[] buffer = new byte[1024];
outStream1 = new ZipOutputStream(new FileOutputStream(zipFileName));
for(int i = 0; i < fileName.length; i++) {
String filePath=audioFile.getAllFiles(fileName[i], Integer.parseInt(userId));
inputStream = new URL("************************server File location***************************").openStream();
String fileNaming = fileName[i];
String[] tempFile = fileNaming.split("\\.");
String tempFileExt=tempFile[1];
String temporaryFile=tempFile[0]+"."+tempFileExt;
fos = new FileOutputStream(temporaryFile);//here is the problem(temporary file created in my server -bin folder.but i dont want this to create)
int length = -1;
while ((length = inputStream.read(buffer)) > -1) {
fos.write(buffer, 0, length);
}
inStream = new FileInputStream(fileName[i]);
outStream1.putNextEntry(new ZipEntry(fileName[i]));
fos.close();
inputStream.close();
while ((bytesRead = inStream.read(buffer)) > 0) {
outStream1.write(buffer, 0, bytesRead);
}
}
inStream.close();
outStream1.closeEntry();
outStream1.close();
int bytesRead1 = 0;
byte[] buff = new byte[1024];
ByteArrayOutputStream bao = new ByteArrayOutputStream();
FileInputStream inStream1 =new FileInputStream(zipFileName);
while ((bytesRead1 = inStream1.read(buff)) != -1)
{
bao.write(buff, 0, bytesRead1);
}
byte[] videoBytes = bao.toByteArray();
response.setContentLength(videoBytes.length);
outStream = response.getOutputStream();
outStream.write(videoBytes);
outStream.flush();
outStream.close();
bao.close();
response.flushBuffer();
} catch (Exception ex) {
ex.printStackTrace();
}
}
For whatever reason, you're copying the files twice. Once, to the file system via inputStream and fos, and the second time to the ZipFile, via inStream and outStream1.
Seems like you can simply remove all of the code related to inputStream and fos, and you won't create the files on your filesystem.
I want to return file (read or load) from method and then remove this file.
public File method() {
File f = loadFile();
f.delete();
return f;
}
But when I delete a file, I delete it from disk and then exists only descriptor to non-existing file on return statement. So what is the most effective way for it.
You can't keep the File handle of deleted file, rather you can keep the data in a byte array temporarily, delete the file and then return the byte array
public byte[] method() {
File f =loadFile();
FileInputStream fis = new FileInputStream(f);
byte[] data = new byte[fis.available()];
fis.read(data);
f.delete();
return data;
}
// Edit Aproach 2
FileInputStream input = new FileInputStream(f);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int bytesRead = input.read(buf);
while (bytesRead != -1) {
baos.write(buf, 0, bytesRead);
bytesRead = input.read(buf);
}
baos.flush();
byte[] bytes = baos.toByteArray();
you can construct the file data from byte array
However, my suggestion is to use IOUtils.toByteArray(InputStream input) from Jakarta commons, why do you want re write when already in plate
Assuming you want to return the file to the browser, this is how I did it :
File pdf = new File("file.pdf");
if (pdf.exists()) {
try {
InputStream inputStream = new FileInputStream(pdf);
httpServletResponse.setContentType("application/pdf");
httpServletResponse.addHeader("content-disposition", "inline;filename=file.pdf");
copy(inputStream, httpServletResponse.getOutputStream());
inputStream.close();
pdf.delete();
} catch (Exception e) {
e.printStackTrace();
}
}
private static int copy(InputStream input, OutputStream output) throws IOException {
byte[] buffer = new byte[512];
int count = 0;
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
}
return count;
}
I am trying to copy the image files from resource folder to local system with using following code.
InputStream inStream = null;
OutputStream outStream = null;
File bfile = new File(directoryPath + "/icons/" + outputFileName);
inStream = MyClass.class.getClassLoader().getResourceAsStream("/images/" + imgFileName);
try {
outStream = new FileOutputStream(bfile);
byte[] buffer = new byte[1024];
int length;
if (inStream != null && outStream != null) {
// copy the file content in bytes
while ((length = inStream.read(buffer)) > 0) {
outStream.write(buffer, 0, length);
}
inStream.close();
outStream.close();
}
System.out.println("File is copied successful!");
} catch (IOException e) {
e.printStackTrace();
}
This code works absolutely fine when I run through eclipse. But when i build the product, icons are not getting copied to local system.
I also tried
inStream = MyClass.class.getResourceAsStream("/images/" + imgFileName);
but no luck.
Any thoughts!
For opening an input stream consider using FileLocator API:
FileInputStream is = null;
FileOutputStream fo = null;
FileChannel inputChannel = null;
FileChannel outputChannel = null;
File bfile = new File(directoryPath + "/icons/" + outputFileName);
try {
is = FileLocator.openStream(Activator.getDefault().getBundle(), new Path("/images/" + imgFileName), false);
inputChannel = is.getChannel();
fo = new FileOutputStream(bfile);
outputChannel = fo.getChannel();
outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
} finally {
// close everything in finally
}
Also, please note, that it is better to close streams and channels in the finally block
I am trying to build a file transfer mechanism between 2 Java socket client. The sender client would include this sorta snippet:
FileInputStream fis = null;
BufferedInputStream bis = null;
BufferedOutputStream outStream = null;
byte[] fileBytes = new byte[(int) file.length()];
int bytesRead = 0;
try {
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
outStream = new BufferedOutputStream(socket.getOutputStream());
bytesRead = bis.read(fileBytes, 0, fileBytes.length);
outStream.write(fileBytes, 0, fileBytes.length);
} catch (IOException _IOExc) {
Logger.getLogger(ChatClient.class.getName()).log(Level.SEVERE,
null, _IOExc);
//QuitConnection(QUIT_TYPE_DEFAULT);
}
The server mediator would look like:
public void run() {
assert (outSocket != null);
byte[] bytes = new byte[fileSize];
try {
System.out.println("inStream " + inStream.available());
outStream = new BufferedOutputStream(outSocket.getOutputStream());
inStream.read(bytes, 0, fileSize);
outStream.write(bytes, 0, fileSize);
outStream.flush();
} catch (IOException ex) {
Logger.getLogger(FileTransport.class.getName()).log(Level.SEVERE,
null, ex);
}
}
the destination client:
public void run() {
try {
System.out.println("Start reading...");
int len = 1024;
BufferedInputStream inStream = new BufferedInputStream
(client.user.getClientSocket().getInputStream());
while ((bytesRead = inStream.read(fileBytes, 0, len)) >
0 && current < fileSize) {
current = current + bytesRead;
System.out.println("current "+ current);
bos.write(fileBytes, 0, bytesRead < len ? bytesRead : len);
}
bos.flush();
bos.close();
} catch (IOException ex) {
Logger.getLogger(ReadFileThread.class.getName()).log(Level.SEVERE,
null, ex);
} catch (InterruptedException e) {
}
}
Both the server and destination client is passed "fileSize" in advance, the problem now is server side get slight less data and the clientB keep reading only 8192 bytes of data from server and can never get out the loop.
Many thanks
Kev
Don't ignore the result of the read() method. It returns the number of bytes that have been read, which is not necessarily the length of the file. read() must always be called in a loop, until it returns -1.
And don't, ever, use available(). It doesn't return what you think it returns. Just loop until read() returns -1 or until the number of read bytes reaches the expected count.
Read the IO tutorial.
I am creating one directory i.e file and storing the bitmap images into that file,now how to convert it into byte array
File myDir = new File(root + "/saved_images");
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-"+ n +".jpg";
File file = new File (myDir, fname);
if (file.exists ()) file.delete ();
try {
FileOutputStream out = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
If you just want to modify your existing code to write the image to a byte array instead of a file, then replace the try block with this code:
ByteArrayOutputStream out = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 90, out);
bytes = out.getBytes();
... where bytes has type byte[], and get rid of the code that generates the filename and deletes the existing file if it exists. Since you writing to a ByteArrayOutputStream, there is not need to call flush() or close() on out. (They won't do anything.)
Not exactly sure what you're trying to do, but you can try something like:
InputStream is = ...
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[some huge number, power of 2 preferably];
while ((nRead = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
buffer.flush();
byte[] byteArray = buffer.toByteArray();
Just Use this to read the file where you kept.
// Returns the contents of the file in a byte array.
public static byte[] getBytesFromFile(File file) throws IOException {
InputStream is = new FileInputStream(file);
// Get the size of the file
long length = file.length();
// You cannot create an array using a long type.
// It needs to be an int type.
// Before converting to an int type, check
// to ensure that file is not larger than Integer.MAX_VALUE.
if (length > Integer.MAX_VALUE) {
// File is too large
}
// Create the byte array to hold the data
byte[] bytes = new byte[(int)length];
// Read in the bytes
int offset = 0;
int numRead = 0;
while (offset = 0) {
offset += numRead;
}
// Ensure all the bytes have been read in
if (offset
Courtesy : http://www.exampledepot.com
I have used this code for converting image file into byte araay,
Bitmap bm = BitmapFactory.decodeResource(getResources(),R.drawable.abc);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 40 , bos);
public byte[] bitmapdata = bos.toByteArray();
Log.w("Image Conversion", String.valueOf(bitmapdata.length));
String converted_txt="";
for (int i = 0; i < bitmapdata.length; i++)
{
Log.w("Image Conversion", String.valueOf(bitmapdata[i]));
ba = bitmapdata[i];
converted_txt=converted_txt+bitmapdata[i];
}
try
{
File myFile = new File("/sdcard/myImageToByteFile.jpg");
myFile.createNewFile();
fOut = new FileOutputStream(myFile);
OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut);
myOutWriter.write(ba);
myOutWriter.close();
fOut.close();
}
catch (Exception e)
{
Toast.makeText(getApplicationContext(), e.getMessage(),5000).show();
}