Why does NSFileManager disagree with statfs about disk space remaining? - ios

I've tried two implementations on iOS 12 to get the remaining free disk space.
"The Apple Way"
uint64_t get_disk_bytes_free()
{
uint64_t totalSpace = 0;
uint64_t totalFreeSpace = 0;
NSError *error = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error: &error];
if (dictionary)
{
NSNumber *fileSystemSizeInBytes = [dictionary objectForKey: NSFileSystemSize];
NSNumber *freeFileSystemSizeInBytes = [dictionary objectForKey:NSFileSystemFreeSize];
totalSpace = [fileSystemSizeInBytes unsignedLongLongValue];
totalFreeSpace = [freeFileSystemSizeInBytes unsignedLongLongValue];
}
else
{
LOG_APP("Error Obtaining System Memory Info: Domain = %s, Code = %ld", [[error domain] UTF8String], (long)[error code]);
}
return totalFreeSpace;
}
"The Unix Way" - path is still the Library/Caches path.
struct statfs fs;
if(statfs(path.c_str(),&fs)==0)
{
if(out_total_space) *out_total_space = (xu64) fs.f_bsize * (xu64) fs.f_blocks;
if(out_free_space) *out_free_space = (xu64) fs.f_bsize * (xu64) fs.f_bfree ;
return err_code_ok;
}
The Apple Way returns 4GB free. The Unix Way returns about 10GB free. They both equally report 16GB total (which is correct) but this device has hardly NOTHING on it. Just a couple of apps.
If I go to iPhone Storage in the Settings to see, it shows 11.8GB of 16GB used....almost all of it is used by "System" at the very bottom (8.65GB).
This System usage seems to disappear if i reboot the device but it comes back eventually.
Can someone tell me if there's any good reason for the discrepancy between these two methods? Which one is more reliable/accurate?

Related

storage greater than system

I want to simulate a shortage of storage, so I try to copy files util the storage is full, but I found it will never get to that, and I found the occuped storage is greater than system, how can this happen?
the code is as follows:
+ (void)copeFiles
{
NSString *srcPath = [self cloudStorageCacheFolderPath];
NSLog(#"copy: src path:%# ,size:%f", srcPath, [self sizeOfcloudStorageCacheFolder]);
int base = 300;
int i = base;
while (1) {
i++;
if (i > base + 100) {
break;
}
NSInteger freeSizeM = [self freeFileStorageSize];
if (freeSizeM > 1024) {
NSString *newFilePath = [NSString stringWithFormat:#"%#-%d", srcPath, i];
[self copyFolderContentFromSrc:srcPath toDestPath:newFilePath];
NSLog(#"copy: i:%d, freeSizeM:%li", i, (long)freeSizeM);
}else {
break;
}
}
}
+ (void)copyFolderContentFromSrc:(NSString *)srcPath toDestPath:(NSString *)dstPath
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSLog(#"copy: src:%# dst:%#", srcPath, dstPath);
BOOL isDir;
if (![fileManager fileExistsAtPath:dstPath isDirectory:&isDir] || !isDir) {
BOOL sucess = [fileManager createDirectoryAtPath:dstPath withIntermediateDirectories:YES attributes:nil error:nil];
NSLog(#"copy: isDir:%d sucess:%d", isDir, sucess);
}
NSArray* array = [fileManager contentsOfDirectoryAtPath:srcPath error:nil];
int i = 0;
for (NSString *fileName in array) {
i++;
NSString *srcFullPath = [srcPath stringByAppendingPathComponent:fileName];
NSString *toFullPath = [dstPath stringByAppendingPathComponent:fileName];
NSError *error;
BOOL isSucess = [fileManager copyItemAtPath:srcFullPath toPath:toFullPath error:&error];
NSLog(#"copy:%d", i);
if (!isSucess) {
NSLog(#"copy:error:%#", error);
}
}
}
image1
image2
The images may be invisible, so I describe the phenomenon simply in advance.My iphone is 32GB in total, but the available storage is 93GB showed in setting.
Yes, It will also increase if you run it again :)
The reason behind it is that It will store the reference only not an actual file. and I have done the same in my mac system to fill the space for simulator and I have ended up with same 256GB system showing 4.3 TB of space
In Device, you can fill space using record a video and still you can not get that error because Apple will manage it like this way.
1) Delete all temporary files that were stored in All App directory.
2) And then Clear cache memory.
Apple will manage the storage space management very well and there is still some mystery about it.

Can we check programmatically if iOS device has low memory situation?

I have a situation where lots of transactions have to uploaded to the server. I have made this job asynchronously using NSManagedObjectContext performBlock: method that performs block on the NSManagedObjectContext queue. So in the async-block how can I observe the low memory warning! Instead of observing I would like to determine if the device has enough free memory then only upload data. Otherwise if it has low-memory situation then wait till low-memory happens and then resume the upload job.
You can check free disk space of your iOS device before upload data to avoid low-memory situation.
+(uint64_t)getFreeDiskspace {
uint64_t totalSpace = 0;
uint64_t totalFreeSpace = 0;
NSError *error = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error: &error];
if (dictionary) {
NSNumber *fileSystemSizeInBytes = [dictionary objectForKey: NSFileSystemSize];
NSNumber *freeFileSystemSizeInBytes = [dictionary objectForKey:NSFileSystemFreeSize];
totalSpace = [fileSystemSizeInBytes unsignedLongLongValue];
totalFreeSpace = [freeFileSystemSizeInBytes unsignedLongLongValue];
NSLog(#"Memory Capacity of %llu MiB with %llu MiB Free memory available.", ((totalSpace/1024ll)/1024ll), ((totalFreeSpace/1024ll)/1024ll));
} else {
NSLog(#"Error Obtaining System Memory Info: Domain = %#, Code = %ld", [error domain], (long)[error code]);
}
return totalFreeSpace;
}

How to check sufficient space on iPhone device before downloading audio files from server

i am able to download audio files successfully.. i am able to get the device free space….but my requirement is before downloading file i want to check is there enough space on iPhone if yes then download and if not then user can see some alert message like “your device does not have enough memory space.”
plz guide me any body.. Thanks in advance.
- (uint64_t)freeDiskspace
{
uint64_t totalSpace = 0;
uint64_t totalFreeSpace = 0;
__autoreleasing NSError *error = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error: &error];
if (dictionary) {
NSNumber *fileSystemSizeInBytes = [dictionary objectForKey: NSFileSystemSize];
NSNumber *freeFileSystemSizeInBytes = [dictionary objectForKey:NSFileSystemFreeSize];
totalSpace = [fileSystemSizeInBytes unsignedLongLongValue];
totalFreeSpace = [freeFileSystemSizeInBytes unsignedLongLongValue];
NSLog(#"Memory Capacity of %llu MiB with %llu MiB Free memory available.", ((totalSpace/1024ll)/1024ll), ((totalFreeSpace/1024ll)/1024ll));
}
else {
NSLog(#"Error Obtaining System Memory Info: Domain = %#, Code = %ld", [error domain], (long)[error code]);
}
return totalFreeSpace;
}
You wouldn't download a 12.8MB audio file if you have 12.9MB free space. That's asking for trouble. Check for 100MB free space. Then check if an iPhone misbehaves or gives the user trouble with only 100MB free space, and increase the number if it does.

AVFoundation Recording Not Enough Disk Space Error Code 11807

I am writing a small video that is only 100kb in size. My phone has about 20mb left on disk, but when I try create a recording using AVFoundation and AVCaptureMovieFileOutput, I get the error:
2014-06-15 10:40:19.511 wave[551:690b] ERROR:
Error Domain=AVFoundationErrorDomain
Code=-11807 "Operation Stopped" UserInfo=0x157cde20
{NSLocalizedRecoverySuggestion=There
is not enough available space to continue the file writing.
Make room by deleting existing videos or photos
I am setting the
self.movieFileOutput.minFreeDiskSpaceLimit = //space available in bytes
thinking it would override this default behavior, but it's not. Any idea how to continue allow for recording given the disk space parameters?
Update - here is the code I'm using to get free space:
-(uint64_t)getFreeDiskspace {
uint64_t totalSpace = 0;
uint64_t totalFreeSpace = 0;
NSError *error = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error: &error];
if (dictionary) {
NSNumber *fileSystemSizeInBytes = [dictionary objectForKey: NSFileSystemSize];
NSNumber *freeFileSystemSizeInBytes = [dictionary objectForKey:NSFileSystemFreeSize];
totalSpace = [fileSystemSizeInBytes unsignedLongLongValue];
totalFreeSpace = [freeFileSystemSizeInBytes unsignedLongLongValue];
NSLog(#"Memory Capacity of %llu MiB with %llu MiB Free memory available.", ((totalSpace/1024ll)/1024ll), ((totalFreeSpace/1024ll)/1024ll));
} else {
NSLog(#"Error Obtaining System Memory Info: Domain = %#", error);
}
return totalFreeSpace;
}

How to get available memory in IOS ? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to get information about free memory and running processes in an App Store approved app? (Yes, there is one!)
How to get available memory in IOS ? I don't know..
I googled, then I know how can i get the physical memory, user memory and used mem, free mem in VM.
But. the memory size is different with which is Settings -> General -> About -> Avaliable.
I want to know "Avaliable" in Settings.
Have a nice day .
found this on here a few months back cant remember who originally posted. Is this what you are looking for?
- (uint64_t)freeDiskspace
{
uint64_t totalSpace = 0;
uint64_t totalFreeSpace = 0;
__autoreleasing NSError *error = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error: &error];
if (dictionary) {
NSNumber *fileSystemSizeInBytes = [dictionary objectForKey: NSFileSystemSize];
NSNumber *freeFileSystemSizeInBytes = [dictionary objectForKey:NSFileSystemFreeSize];
totalSpace = [fileSystemSizeInBytes unsignedLongLongValue];
totalFreeSpace = [freeFileSystemSizeInBytes unsignedLongLongValue];
NSLog(#"Memory Capacity of %llu MiB with %llu MiB Free memory available.", ((totalSpace/1024ll)/1024ll), ((totalFreeSpace/1024ll)/1024ll));
} else {
NSLog(#"Error Obtaining System Memory Info: Domain = %#, Code = %#", [error domain], [error code]);
}
return totalFreeSpace;
}

Resources