No space left on device but SD card not full - android

I have android app which downloads files from google docs to SD card on device. (reason: have PDF-s which I cannot open within app).
It writes successfully to SD card until I get to ~8000th file of 10000 total.
Code for writing to SD:
InputStream is = response.getContent();
FileOutputStream fos = new FileOutputStream(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/"+preferences.getString("username", "manas11")+"/" + tmp_entry.resourceID.replace(":","~_~")+"~_~"+tmp_entry.title));
byte[] buf = new byte[1024];
int len;
while((len=is.read(buf))>0)
fos.write(buf,0,len);
Exception thrown by line 2:
java.io.FileNotFoundException: /mnt/sdcard/matulic.realestate.hr/file~_~0B3n2EnTf5ATnYTJkNTNmM2QtZDJjYy00YjNhLWJlZjQtYTE4MTU5MjI2N2E5~_~Kuæa Marina Sevid 399.00 m2 - LJETNA AKCIJA IZVRSN - k359.txt (No space left on device)
SD card is microSD™ memory card (SD 2.0 compatible), 8gb, FAT32 formatted. Im using Desire HD.
As you can see filenames are long.
I save files to directory in /mnt/sdcard/ which state after exception is (by Astro):
size: 519,668,573 bytes
number of files: 8037
device free size: 4.91 G
Is there any limit for writing to SD I dont know about?
Thank you

I believe this stackoverflow question will answer your question.
Is there a limit for the number of files in a directory on an SD card?
I also checked out some of the information myself and found it basically comes down to a limit in the number of files and the length of the file name. From what I read in the Microsoft document referenced in the link above http://msdn.microsoft.com/en-us/windows/hardware/gg463080.aspx you have a problem with the length of your file names.
First is the length of your file names. Longer file names take up more space. There is a limit of 65,536 32 byte entries in the directory. This is because the maximum size of a directory file container is 2,097,152 bytes (65536*32). However, if your file names are longer than 8.3 they will take up more than just one entry. Also long file names take up more space than simply the sum of their characters. There is overhead to the filesystem that creates things like checksums and a short 8.3 file name to go along with it.
Best advice would be to shorten the file names dramatically and that should solve your problem.
Hope this helps.

It might be a limitation of FAT32.
A FAT32 directory can have 65,536 directory entries. Each file and
subdirectory takes from two to thirteen entries, depending on the
length of its name, so those entries can disappear long before you
think you've used them all up. Your total of 22,657 files could very
easily use 65,000 entries.
From here.
Have you tried reducing the file name when storing it locally? Does it really have to be that long?

Related

Detect the internal storage memory?

I am working on an app which moves a file from sdcard to internal memory storage .What I need is :
1.To detect the size of the file to be moved.
2.Detect the size of free memory in internal storage.
3.Compare both?
This would give some alert whenever the free memory is less than the size of the file.
How can I do the first two points.If anyone worked on similar type of problem?
long file_size = file.length();
File data_path = Environment.getDataDirectory();
StatFs stat = new StatFs(data_path.getPath());
long free_internal_memory = stat.getBlockSize() * stat.getAvailableBlocks();
I've done something similar, but then for multiple (music) files in a directory, and across any mount point available to the system. I'm not 100% sure the explanation below will be applicable for the internal storage, but it should at least give you some useful pointers.
You can easily get the size of a file by calling .length() on it:
long fileSize = someFile.length();
Note that in case someFile is actually a directory, the result is not defined. Hence, to get a directory's size, iterate over all its children (which on its turn may again contain directories of course).
For retrieving information about the file system's space, I used the statFs class, which is nothing more but a Java wrapper for statfs(). Calculating the available space is a simple multiplication:
// 'fromFreeBytes' is the source file/directory size
StatFs toDirStats = new StatFs(mToDir.getAbsolutePath());
long toFreeBytes = ((long)toDirStats.getAvailableBlocks() * (long)toDirStats.getBlockSize());
if (toFreeBytes < fromFreeBytes) {
//insufficient available space
}
Finally, it's important to remember that if you're going to move files between different mount points, you cannot use File's renameTo(...) method. In stead you'll have to use an InputStream and OutputStream to copy the data across.
Good luck!

FileNotFoundExcecption while inserting image into SDCard

I want to insert images into my SDCard.So I used below code
m_cImagePath = "/sdcard/"+ String.format("%d.jpg", System.currentTimeMillis());
FileOutputStream lObjOutStream = null;
try {
lObjOutStream = new FileOutputStream(m_cImagePath);
if (null != lObjOutStream && null != finalBitmap) {
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 85, lObjOutStream);
lObjOutStream.close();
}catch(FileNotFoundException fe){
fe.printStackTrace();
}
Sometimes it is giving FileNotFoundException even my SDCard had memory.When I remove some images from sdcard again it is working smoothly.Why this Happend?How can i know that file is inserted successfully in SDCard and Is there any functionality in Java1.5 to know available space of the SDCard like java 1.6?How can i know file length which is not before inserting into the SDCard(I searched in google and found that
"when the file is not physically there
then file.length() always gives 0"
).But before inserting i want to know the length of the file.Then Comparing this space to available SDCard space is simple.
Note :I had an idea to use Unix command
df sdcard
using in
Runtime class
to found SDCard space.
Please give me an idea in this problem.
Regards,
Android Developer
Never never never never never hardcode /sdcard in an Android application. First, it's wrong on Android 2.2+. Second, it's wrong on other devices as well. Always use Environment.getExternalStorageDirectory() for the root of external storage.
Is there any functionality in Java1.5 to know available space of the SDCard like java 1.6?
android.os.StatFs has what you need.

Adding a big text file to assets folder

I'm developing an Android 2.2 application.
I want to add some big text files (4.5MB or more) to Android project.
First I don't know if I can add such kind of big files to assets folder. But, if I can, is it possible to compress them?
How can I compress files? and decompress?
Any other better way to add big text files to Android project?
Thanks.
Files over 1 MB placed in the assets folder won't be readable from your app (It'll throw an exception). This is because they get compressed during the build process, and thus the phone requires substantial resources to uncompress them when on the handset.
I believe you can place them in the raw folder, where they won't get compressed or use an extension that AAPT assumes is already compressed (see here)
However, It's not good having a 4.5 MB text file uncompressed sitting in the APK, It's wasted space that could be handled better. Try thinking about downloading the data on first use instead, or splitting the file into chunks as suggested before so that AAPT can compress it.
Another approach is you should copy your file into SD card during the first run using IOUtils. Here also be careful also because if you will copy each byte then more resources will be occupied.
It works for me, I needed to put 30MB large zip file into Assets folder because of Client's requirement.
You can, but sometimes it gives problems. You don't have to compress it, because the package itself is compressed (the .APK), in fact, anything that you store in the assets folder is uncompressed when you read it. With regards to the size of the file, you may want to cut it and put smaller parts of the file inside the assets folder.
I believe the assets directory (except for raw) is already compressed. Also the Android Market will soon/is allowing apks of 50MB in size. Try it first and then see if you have any problems.
You need to do fragmentation work for that 4.5 MB text file. Where you need to split the text file into five files with 1 MB maximum size. Then again you need to rejoin them like this:
OutputStream databaseOutputStream = new FileOutputStream(outFileName);
InputStream databaseInputStream;
byte[] buffer = new byte[1024];
int length;
databaseInputStream = myContext.getResources().openRawResource(
R.raw.outfileaaa);
while ((length = databaseInputStream.read(buffer)) > 0) {
databaseOutputStream.write(buffer);
}
databaseInputStream.close();
databaseInputStream = myContext.getResources().openRawResource(
R.raw.outfileaba);
while ((length = databaseInputStream.read(buffer)) > 0) {
databaseOutputStream.write(buffer);
}
databaseInputStream.close();
databaseOutputStream.flush();
databaseOutputStream.close();

Android Assets No Value Read?

AssetManager assets = myContext.getAssets();
String[] files = assets.list("MyFolder");
InputStream myInput = assets.open("MyFolder/" + files[0]);
int i = myInput.read();
in this case 'i' is -1 meaning nothing read.
Why would nothing be there if the file is there, the variable 'files' has the file as well.
Do I need to do anything to the file I put into the Assets folder in get it to be readable?
NOTE: When I use a small text file it works. When I use a 10 meg file, it does not. (The 10 meg is a Sqlite database I need to install)
Rename the file to XXXXXX.png so that it is not compressed, then it can be copied over.
You cannot put a 10MB file inside an APK. You will need to slice that into 10 1MB files. Better yet, distribute the database in some other way, such as downloading it to the SD card on the first run of the application. Many users will be unable to install your APK if it is that large.

Android: how to get storage used by an application

I have an application which has a directory created into SDCard where I save photos. I would like to know how much space is using that dir on SDCard in order to show that info to the user.
I'm not sure if its the best solution but you could do something like that:
int totalSize = 0;
File root = new File("path to one of your file").getParentFile();
File[] files = root.listFiles();
for (File file: files) {
totalSize = totalSize + file.length();
}
Then totalSize contains the sum of all files in the directory in bytes. depending on the structure of your directory (e.g. are there any subdirectories?) you have to adapt the code.
Edit:
After a little bit of researching I'm almost sure that there is no method in java which directly returns the size of a directory. See e.g. this link:
http://forums.sun.com/thread.jspa?threadID=640296
However in this link http://www.codemiles.com/java/get-directory-size-in-java-t1242.html there is a recursive version of my code mentioned above to calculate any subdirectories if availiable.
There is also a small library which can do what you want:
http://commons.apache.org/io/api-release/index.html
However then you have to import this library. I personally would prefer to write this short method by myself.

Categories

Resources