I am creating an application were i am reading the content from a file present in internal storage and displaying in the application.
I am creating a file on the desktop and transferring that file to the mobile using usb cable.If sdcard is present the file will be stored in sdcard and for accessing the file i found the following code and it worked for me.
File path = Environment.getExternalStorageDirectory();
/storage/sdcard0/Filename.txt is the path which i am getting when i run the above code.If file is present in sdcard it is returning true else false.
If sdcard is not present and when i transfer the file from desktop to mobile it gets stored in internal storage.in this case how do i access my file.
In some cases i have come to know that sdcard0 is internal storage and not the external storage.
Which is the best way to find the file existence in internal storage of the mobile and not apps internal storage. please help.
Thanks in advance
To find out the path for your app's internal storage you can use the following commands:
Context context = getApplicationContext();
or
Context context = getApplication();
String dir = context.getFilesDir().getAbsolutePath();
String dir = context.getFilesDir().getPath();
getFilesDir() returns a File object that you can get the path from there. Then you can use that path to transfer your file. Also read below.
See here on how to write a file to internal storage and here on getting the path for internal storage.
The following code gives you the path for the your file in internal storage and then you can open it:
String yourFilePath = context.getFilesDir() + "/" + "filename";
File yourFile = new File( yourFilePath );
You can also use the following approach explained in here
StringBuffer fileContent = new StringBuffer("");
FileInputStream fis = context.openFileInput(filename);
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) != -1) {
fileContent.append(new String(buffer));
}
The above solution opens input stream to the file name provided using the context that gives the location where the files are stored in internal storage. In the while loop it reads from the input stream (up to size of buffer) every iterator and adds the read data to StringBuilder instance. The loop terminates when the length of the read data from input stream is -1.
If the file is not found, FileNotFoundException will be throw by openFileInput(filename) method.
Related
I tried this link:
How to create text file and insert data to that file on Android
But, it says "No such file or directory". Can anybody help me please? Thanks in advance!
---- Updated answer----
I think you can't create a directory inside the internal storage of the device. Except you've a root access for the app. You can only create the directory inside your app private folder within the following path String path = getFilesDir().
you can use like this below -
File mydir = context.getDir("mydirectory", Context.MODE_PRIVATE); //Creating an internal dir;
File fileWithinMyDir = new File(mydir, "myAwesomeFile"); //Getting a file within the dir.
FileOutputStream out = new FileOutputStream(fileWithinMyDir); //Use the stream as usual to write into the file.
getDir(StringName, int mode) method to create or access directories in internal storage.
/storage/emulated/0/Notes/ will always return No such file or directory except device is rooted and dir.mkDirs() will always return false for this path.
Hope this will help you.
This problem I am facing in title is very similar to this question previously raised here (Azure storage: Uploaded files with size zero bytes), but it was for .NET and the context for my Java scenario is that I am uploading small-size CSV files on a daily basis (about less than 5 Kb per file). In addition the API code uses the latest version of Azure API that I am using in contrast against the 2010 used by the other question.
I couldn't figure out where have I missed out, but the other alternative is to do it in File Storage, but of course the blob approach was recommended by a few of my peers.
So far, I have mostly based my code on uploading a file as a block of blob on the sample that was shown in the Azure Samples git [page] (https://github.com/Azure-Samples/storage-blob-java-getting-started/blob/master/src/BlobBasics.java). I have already done the container setup and file renaming steps, which isn't a problem, but after uploading, the size of the file at the blob storage container on my Azure domain shows 0 bytes.
I've tried alternating in converting the file into FileInputStream and upload it as a stream but it still produces the same manner.
fileName=event.getFilename(); //fileName is e.g eod1234.csv
String tempdir = System.getProperty("java.io.tmpdir");
file= new File(tempdir+File.separator+fileName); //
try {
PipedOutputStream pos = new PipedOutputStream();
stream= new PipedInputStream(pos);
buffer = new byte[stream.available()];
stream.read(buffer);
FileInputStream fils = new FileInputStream(file);
int content = 0;
while((content = fils.read()) != -1){
System.out.println((char)content);
}
//Outputstream was written as a test previously but didn't work
OutputStream outStream = new FileOutputStream(file);
outStream.write(buffer);
outStream.close();
// container name is "testing1"
CloudBlockBlob blob = container.getBlockBlobReference(fileName);
if(fileName.length() > 0){
blob.upload(fils,file.length()); //this is testing with fileInputStream
blob.uploadFromFile(fileName); //preferred, just upload from file
}
}
There are no error messages shown, just we know that the file touches the blob storage and shows a size 0 bytes. It's a one-way process by only uploading CSV-format files. At the blob container, it should be showing those uploaded files a size of 1-5 KBs each.
Instead of blob.uploadFromFile(fileName); you should use blob.uploadFromFile(file.getAbsolutePath()); because uploadFromFile method requires absolute path. And you don't need the blob.upload(fils,file.length());.
Refer to Microsoft Docs: https://learn.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-java#upload-blobs-to-the-container
The Azure team replied to a same query I've put on mail and I have confirmed that the problem was not on the API, but due to the Upload component in Vaadin which has a different behavior than usual (https://vaadin.com/blog/uploads-and-downloads-inputs-and-outputs). Either the CloudBlockBlob or the BlobContainerUrl approach works.
The out-of-the-box Upload component requires manual implementation of the FileOutputStream to a temporary object unlike the usual servlet object that is seen everywhere. Since there was limited time, I used one of their addons, EasyUpload, because it had Viritin UploadFileHandler incorporated into it instead of figuring out how to stream the object from scratch. Had there been more time, I would definitely try out the MultiFileUpload addon, which has additional interesting stuff, in my sandbox workspace.
I had this same problem working with .png (copied from multipart files) files I was doing this:
File file = new File(multipartFile.getOriginalFilename());
and the blobs on Azure were 0bytes but when I changed to this:
File file = new File("C://uploads//"+multipartFile.getOriginalFilename());
it started saving the files properly
I have written AWS Lambda code where I need to store an image in /tmp location of aws lambda. Below is my code:
String fileLocation = "loc1/loc2/";
String imageNameWithoutExt = "image1";
//creating directories first below storing the image
boolean status = new File("/tmp/"+fileLocation).mkdirs();
if(status == true){
File targetFile = File.createTempFile(imageNameWithoutExt,".jpg",new File("/tmp/"+fileLocation));
FileOutputStream outStream = new FileOutputStream(targetFile);
outStream.write(buffer);
outStream.close();
}else{
System.out.println("unable to create directory inside /tmp/");
}
And in response, it is printing the else statement:
unable to create directory inside /tmp/
What modification I need to make to write and read the files from /tmp location. Any help would be appreciated.
In this line of code, you are not setting the filename:
//write file in /tmp folder of aws Lambda
File targetFile = new File("/tmp/");
I think maybe you aren't showing all your code, because I don't see where the String image1.jpg in the error message would be coming from, but that filename needs to be added to the parameter you are passing the File constructor.
I've created this code to save a pdf file in sd card, but I want to change the directory that has the saved files, from /sdcard/, to /sdcard/MYDIR/
try {
URL url = new URL(f_url[0]);
URLConnection conection = url.openConnection();
conection.connect();
// getting file length
int lenghtOfFile = conection.getContentLength();
// input stream to read file - with 8k buffer
InputStream input = new BufferedInputStream(url.openStream(), 8192);
// Output stream to write file
OutputStream output = new FileOutputStream("/sdcard/yes.pdf");
To create a directory in Java, use mkdir() or mkdirs() on File.
To correctly create a directory or file on external storage on Android, do not hard-code /sdcard, largely because it is the wrong value on most Android devices. Use Environment.getExternalStorageDirectory() to access the root of external storage.
File dir=new File(Environment.getExternalStorageDirectory(), "MYDIR");
dir.mkdir();
OutputStream output=new FileOutputStream(new File(dir, "yes.pdf"));
The class you need is File. There you have methods like mkdirs() that creates the necessary directories.
You should make sure that you don't use hard coded paths in your application. On some devices your "/sdcard/" will fail. Check the class Environment and use the getExternalStorageDirectory() to get the path of the sd card.
I have a database file in res/raw/ folder. I am calling Resources.openRawResource() with the file name as R.raw.FileName and I get an input stream, but I have an another database file in device, so to copy the contents of that db to the device db I use:
BufferedInputStream bi = new BufferedInputStream(is);
and FileOutputStream, but I get an exception that database file is corrupted. How can I proceed?
I try to read the file using File and FileInputStream and the path as /res/raw/fileName, but that also doesn't work.
Yes, you should be able to use openRawResource to copy a binary across from your raw resource folder to the device.
Based on the example code in the API demos (content/ReadAsset), you should be able to use a variation of the following code snippet to read the db file data.
InputStream ins = getResources().openRawResource(R.raw.my_db_file);
ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
int size = 0;
// Read the entire resource into a local byte buffer.
byte[] buffer = new byte[1024];
while((size=ins.read(buffer,0,1024))>=0){
outputStream.write(buffer,0,size);
}
ins.close();
buffer=outputStream.toByteArray();
A copy of your file should now exist in buffer, so you can use a FileOutputStream to save the buffer to a new file.
FileOutputStream fos = new FileOutputStream("mycopy.db");
fos.write(buffer);
fos.close();
InputStream.available has severe limitations and should never be used to determine the length of the content available for streaming.
http://developer.android.com/reference/java/io/FileInputStream.html#available():
"[...]Returns an estimated number of bytes that can be read or skipped without blocking for more input. [...]Note that this method provides such a weak guarantee that it is not very useful in practice."
You have 3 solutions:
Go through the content twice, first just to compute content length, second to actually read the data
Since Android resources are prepared by you, the developer, hardcode its expected length
Put the file in the /asset directory and read it through AssetManager which gives you access to AssetFileDescriptor and its content length methods. This may however give you the UNKNOWN value for length, which isn't that useful.