BufferInputStream gets FileNotFound exception on existing file - filenotfoundexception

I am trying to access a file that exists in my Download folder. I have android.permission.READ_EXTERNAL_STORAGE (as well as WRITE and MANAGE). I use the following code:
File filePath = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/test.jpg");
int size = (int) filePath.length();
byte[] bytes = new byte[size];
try {
BufferedInputStream buf = new BufferedInputStream(new FileInputStream(filePath));
buf.read(bytes, 0, bytes.length);
buf.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
Global.LogError("File " + filePath.getAbsolutePath() + " was not found");
} catch (IOException e) {
// TODO Auto-generated catch block
Global.LogError("File " + filePath.getAbsolutePath() + " error: " + e.getMessage());
}
I've also tried:
File filePath = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),"/test.jpg");
No matter what I do it hits the FileNotFoundException. Any help on what I'm going wrong.
On a separate note, using Android Studio Chipmunk, when I'm stopped on a breakpoint at the bytes declaration, Android Studio won't show me filePath or size when I try to display them. It tells me no local file with that name. What do I need to do to be able to display locals like these?
Thanks for any help.

Related

Not able to upload image in webapp/resources/images folder

I am not able to upload image with this code, although it is not showing any error but at the same time image is also not saving in folder.
MultipartFile productImage = product.getProductImage();
String rootDirectory = request.getSession().getServletContext().getRealPath("/");
path = Paths.get(rootDirectory + "resources/images/" + product.getProductId() + ".png");
if(productImage != null && !productImage.isEmpty()){
try {
productImage.transferTo(new File(path.toString()));
System.out.println("image edited then saved ");
} catch (Exception ex){
ex.printStackTrace();
throw new RuntimeException("Product image saving failed", ex);
}
}

Unable to write to disk using GridFSFile in springboot 2.0.2

Trying to use code in:
http://javasampleapproach.com/spring-framework/spring-data/springdata-mongodb-gridfstemplate-save-retrieve-delete-binary-files-image-text-files
with springboot 1.5.13.
In this code to retrieve an image use GridFSDBFile like this:
GridFSDBFile imageFile = gridOperations.findOne(new Query(Criteria.where("_id").is(imageFileId)));
and later to save in filesystem use this:
imageFile.writeTo
Baeldung has the same code:
http://www.baeldung.com/spring-data-mongodb-gridfs
I have my project in springboot 2.0.2 and this line:
GridFSDBFile imageFile = gridOperations.findOne(new Query(Criteria.where("_id").is(imageFileId)));
throws an error:
Type mismatch: cannot convert from GridFSFile to GridFSDBFile
so, once I have changed to:
GridFSFile imageFile = gridOperations.findOne(new Query(Criteria.where("_id").is(imageFileId)));
no errors, but now I have not available the method:
writeTo
to write to disk.
UPDATE 1:
imageFileId = "5b0bff8b7cc45b32f43b47f4";
GridFSFile imageFile = gridOperations.findOne(new Query(Criteria.where("_id").is(imageFileId)));
try {
File file = new File("c:/JSA/retrieve/" + imageFile.getFilename());
FileOutputStream streamToDownloadTo = new FileOutputStream(file);
//This line doesn't works
gridFSBucket.downloadToStream(imageFile.getId(), streamToDownloadTo);
streamToDownloadTo.close();
} catch (IOException e) {
// handle exception
System.out.println("error: " + e.getMessage());
} catch (Exception e1) {
System.out.println("error1: " + e1.getMessage());
}
UPDATE 2:
try {
File file = new File("c:/JSA/retrieve/" + imageFile.getFilename());
FileOutputStream streamToDownloadTo = new FileOutputStream(file);
System.out.println("imageFile.getId(): " + imageFile.getId());
System.out.println("streamToDownloadTo: " + streamToDownloadTo.toString());
gridFSBucket.downloadToStream(imageFile.getId(), streamToDownloadTo);
streamToDownloadTo.close();
} catch (IOException e) {
// handle exception
System.out.println("error: " + e.getMessage());
} catch (Exception e1) {
System.out.println("error1: " + e1.getMessage());
}
Console
imageFile.getId(): BsonObjectId{value=5b0bff8b7cc45b32f43b47f4}
streamToDownloadTo: java.io.FileOutputStream#3b20c8e2
This line thrown an exception:
gridFSBucket.downloadToStream(imageFile.getId(), streamToDownloadTo);
and return null
Solved
Inject:
#Autowired
MongoGridFsTemplate mongoGridFsTemplate;
GridFSBucket gridFSBucket = GridFSBuckets.create(mongoGridFsTemplate.mongoDbFactory().getDb());
imageFileId = "5b0bff8b7cc45b32f43b47f4";
GridFSFile imageFile = gridOperations.findOne(new Query(Criteria.where("_id").is(new ObjectId(imageFileId))));
try {
File file = new File("c:/JSA/retrieve/" + imageFile.getFilename());
FileOutputStream streamToDownloadTo = new FileOutputStream(file);
gridFSBucket.downloadToStream(imageFile.getId(), streamToDownloadTo);
streamToDownloadTo.close();
} catch (IOException e) {
// handle exception
System.out.println("error: " + e.getMessage());
} catch (Exception e1) {
e1.printStackTrace();
}

How to use File lock in Spring batch-integration?

In my spring-batch-integration app, file polling invokes the batchjob for eachfile and this application could be running on multiple servers(nodes) but they all are supposed to read a common directory.Now, I wrote a custom locker which takes the lock on file so that any other instance will not be able to process the same file . code as below
public class MyFileLocker extends AbstractFileLockerFilter{
private final ConcurrentMap<File, FileLock> lockCache = new ConcurrentHashMap<File, FileLock>();
private final ConcurrentMap<File, FileChannel> ChannelCache = new ConcurrentHashMap<File, FileChannel>();
#Override
public boolean lock(File fileToLock) {
FileChannel channel;
FileLock lock;
try {
channel = new RandomAccessFile(fileToLock, "rw").getChannel();
lock = channel.tryLock();
if (lock == null || !lock.isValid()) {
System.out.println(" Problem in acquiring lock!!" + fileToLock);
return false;
}
lockCache.put(fileToLock, lock);
ChannelCache.put(fileToLock, channel);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
#Override
public boolean isLockable(File file) {
return file.canWrite();
}
#Override
public void unlock(File fileToUnlock) {
FileLock lock = lockCache.get(fileToUnlock);
try {
if(lock!=null){
lock.release();
ChannelCache.get(fileToUnlock).close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Now, when i invoke my Spring batch and i try to read that file using flatfileitemreader it gives me
org.springframework.batch.item.file.NonTransientFlatFileException
which i believe is coming beacuse file is locked. I did some googling and found that NIOLocker locks the file in a way that even the current thread can't read it. I found a link where it shows how to read the locked file but they are using buffer.
How can I make my file accessible to my FlatfileItemReader.
Please suggest.
Yes, you really can get access to the locked file content only over ByteBuffer:
FileChannel fileChannel = channelCache.get(lockedFile);
ByteBuffer byteBuffer = ByteBuffer.allocate((int) fileChannel.size());
fileChannel.read(byteBuffer);
System.out.println("Read File " + lockedFile.getName() + " with content: " + new String(byteBuffer.array()));
Oh! Yeah. You really pointed to my repo :-).
So, with locker you don't have choice unless copy/paste the file byte[] that way before FlatfileItemReader or just inject some custom BufferedReaderFactory into the same FlatfileItemReader, which converts the locked file to the appropriate BufferedReader:
new BufferedReader(new CharArrayReader(byteBuffer.asCharBuffer().array()));
Based on the link that you shared, looks like you could try the following.
//This is from your link (except the size variable)
FileChannel fileChannel = channelCache.get(lockedFile);
int size = (int) fileChannel.size();
ByteBuffer byteBuffer = ByteBuffer.allocate(size);
fileChannel.read(byteBuffer);
//Additional code that you could try
byte[] bArray = new byte[size];
//Write data to the byte array
byteBuffer.get(bArray);
FlatFileItemReader flatFileItemReader = new FlatFileItemReader();
flatFileItemReader.setResource(new ByteArrayResource(bArray));
//Next you can try reading from your flatFileItemReader as usual
...
Let me know if it doesn't progress your issue.
Solution : I am creating a temporary file with content of the locked file and processing it. Once processing is done i archive that file and remove the locked and temporary both files. Key here is to create a new file with locked file content. code for below is as follows :
File tmpFile = new File(inputFile.getAbsolutePath() + ".lck");
FileChannel fileChannel = MyFileLocker.getChannelCache().get(new File(inputFile.getAbsolutePath()));
InputStream inputStream = Channels.newInputStream(fileChannel);
ByteStreams.copy(inputStream, Files.newOutputStreamSupplier(tmpFile));
Here inputFile is my locked file and tmp file is new file with locked file content. I have also created a method in my locker class to unlock and delete
public void unlockAndDelete(File fileToUnlockandDelete) {
FileLock lock = lockCache.get(fileToUnlockandDelete);
String fileName = fileToUnlockandDelete.getName();
try {
if(lock!=null){
lock.release();
channelCache.get(fileToUnlockandDelete).close();
//remove from cache
lockCache.remove(fileToUnlockandDelete);
channelCache.remove(fileToUnlockandDelete);
boolean isFiledeleted = fileToUnlockandDelete.delete();
if(isFiledeleted){
System.out.println("File deleted successfully" + fileName);
}else{
System.out.println("File is not deleted."+fileName);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

Open a .Bat Using Java Apllication

I'm trying to Open the CMD Using java + Applying code to it to open an .jar so the applications output is shown in the .bat file.
can someone tell me how to do it?
This is the code it got,it does run excecute the file but the CMD doesnt show.
btnTest.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
String Bat = "C:"+File.separatorChar+"Users"+File.separatorChar+"Gebruiker"+File.separatorChar+"AppData"+File.separatorChar+"Local"+File.separatorChar+"Temp"+File.separatorChar+"hexT"+File.separatorChar+"run.bat";
Runtime rt = Runtime.getRuntime();
try {
rt.exec(Bat);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Edited: This works for me:
String Bat = "C:\\app.bat"; //Try to use \\ as path seperator
try {
Runtime.getRuntime().exec("cmd /c start " + Bat);
} catch (IOException e) {
e.printStackTrace();
}
Define this :
FileWriter writer;
then in your try/catch do the following :
try {
writer = new FileWriter("test.txt");
Process child = rt.exec(Bat);
InputStream input = child.getInputStream();
BufferedInputStream buffer = new BufferedInputStream(input);
BufferedReader commandResult = new BufferedReader(new InputStreamReader(buffer));
String line = "";
try {
while ((line = commandResult.readLine()) != null) {
writer.write(line + "\n");
}
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
This will read the output as a buffer line by line and write it into a text file

Calling a method to read from a text file with BufferedReader

I searched around for this but I could not find a soultion.
Sorry about my bad description. Im not very good at this.
I have a UI class
Its calling a "lotto" class.
That lotto classes constructor is called a method named readData()
readData is reading from a file using BufferedReader
Im not getting an error message but its just not reading.
It gets stuck at BufferedReader fr = new BufferedReader... and goes to the catch thing.
If its a file not found problem how would i make it track where my file is. Im using eclipse and the program is stored on my usb. I need to hand it in to my teacher so i cant just put a location in. Is there code that tracks where my program is then takes the file from that folder?
Here is the code being used.
import java.io.*;
//contructor
public Lotto()
{
try
{
readData();
nc = new NumberChecker();
}
catch(IOException e)
{
System.out.println("There was a problem");
}
}
private void readData() throws IOException
{
//this method reads winning tickets date and pot from a file
BufferedReader file = new BufferedReader (new FileReader("data.txt"));
for(int i=0;i<5;i++)
{
System.out.println("in "+i);
winningNums[i] = file.readLine();
winningDates[i] = file.readLine();
weeksMoney[i] = Integer.parseInt(file.readLine());
System.out.println("out "+i);
}
file.close();
}
if you get an error in this line of code
BufferedReader file = new BufferedReader (new FileReader("data.txt"));
Then it is probably a FileNotFoundException
Make sure that the data.txt file is in the same folder as your compiled .class file and not the .java source.
It would be best to use a proper root to your file ex. c:\my\path\data.txt
And don't forget the \
Try surrounding the BufferedReader in a try catch and look for a file not found exception as well as IO exception. Also try putting in the fully qualified path name with double backslashes.
BufferedReader file;
try {
file = new BufferedReader (new FileReader("C:\\filepath\\data.txt"));
for(int i=0;i<5;i++)
{
System.out.println("in "+i);
winningNums[i] = file.readLine();
winningDates[i] = file.readLine();
weeksMoney[i] = Integer.parseInt(file.readLine());
System.out.println("out "+i);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Resources