I have got an iPhone application where I archive permanent data in the documents folder of the application (arrays, dictionaries). I read/write from and to the documents folder quite frequently and I would like to know whether this is considered a bad habit. Wouldn't it be better if I had a singleton class, read and write to arrays there and then, only when the application quits, write this data to the documents folder ? I do not see/feel any performance issues right now on my iPhone 5, but I wanted to know whether this is a bad practise.
FLASH memory has limited write capability - a long time ago it was rated in some increment of thousands. Not sure where it is today.
That said, if your app is using the standard file system APIs, then the system is using the file cache, and you might open a file, read it then change it many times without the file system ever writing to flash. The system may sync to flash occasionally, but that process is opaque - no way to really know when or why iOS does it.
The UNIX APIs allow for syncing the file system cache to the storage system (iOS this is FLASH), but if you are not using that then you are probably not doing much I/O at all given what you say above.
Given the lack of Apple discouraging developers from writing to the file system, I for sure would not worry about this.
But, if you said you were writing gigabytes of image data every few minutes - well - that might be a problem.
Related
I used log4j (v. 1) in the past and was glad to know that a major refactoring was done to the project, resulting in log4j 2, which solves the issues that plagued version 1.
I was wondering if I could use log4j 2 to write to data files, not only log files.
The application I will be soon developing will need to be able to receive many events from different sources and write them very fast either to a data file or to a database (I haven't decided which yet).
The thread that receives the events must not be blocked by I/O while attempting to write events, so log4j2's Asynchronous Loggers, based on the LMAX Disruptor library, will definitely fit this scenario.
Moreover, my application must be able to recover either from a 'not enough space on disk' or 'unable to reach database' conditions, when writing to a data file or to a database table, respectively. In other words, when the application runs out of disk space or the database is temporarily unavailable, my application needs to store events in memory and wait for storage to become available and when it does, write all waiting events to disk or database.
Do you think I can do this with log4j?
Many thanks for your help.
Regards,
Nuno Guerreiro
Yes.
I'm aware of at least one production implementation in a similar scenario, where in gathered events are written to disk at high throughput.
Write to a volume other than your system volume to minimize the chances of system crashes due to disk space overrun.
Upfront capacity planning can help in ensuring h/w configuration with adequate resources to handle projected average load and bursts, for a reasonable period of time.
Do not let the system run out of disk space :). Keep track of disk usage, and proactively drop older data in extreme circumstances.
My app has to make sure that there is always a minimum amount (maybe 5-10 MB) of free disk space available, for it to operate correctly. I have to save important data to file, otherwise everything is going to be corrupted.
The main problem is: What if the user downloads my app and he had EXACTLY that amount of disk space free that he needed for the app (without my on first startup created data)
When he's now starting the app I try to do some initial setup stuff - here I have to write around 2-3 MB to file and this space must be free.
What can I do to achieve this?
You can do two things:
First, when your application starts, you can find out the available space using NSFileManager.attributesForFilesystemofPath:. If the amount of space is low (and 5 MB free is really low, you can warn the user and maybe even refuse to start actions in your app that require this available space.
Second, you could create a scratch file. If you know you need 5MB storage, then maybe you can allocate a 5MB file and use that file for your storage.
You don't specify what you need to store on disk but if it were for example one file then you could write this data over your 5MB scratch file instead of opening a new file.
This requires some extra bookkeeping, but you do get guaranteed space for your data.
In short, you can't. You will need to write your code to have an initial startup that checks to see if there is enough disk space to do your initial setup, and display an error if not. I haven't tried to do this on iOS before so I'm not sure what the sandbox allows you to do off the top of my head. I'd have to go read up in the iOS file system docs. That's what I suggest you do.
I am making a some complex app, in which every detail is imp. i have some questions
1. how much storage limit we have, if we plan to save big files on core data/cache.
2. Whats the RAM limit on iphone? Actually searching for some table that can give detailed info about IOS devices on this. Because i need to handle memory warnings and defend App crashes.
3. Its better to save images in cache or core data, assume you have a lot of images approx. 200-250.
Thanks
1) I am not aware of any storage limit. Obviously, you will never get 64GB or more - since no device is larger ;-). My wife's facebook app consumes >5GB at the moment... I suppose they did something wrong. The only important point is to fail gracefully (show a dialog, clean some space, ...) if the storage is full.
2) The RAM limit varies depending on the iPhone model and the currently running applications. Also there are some iPods with less memory in market. 30MB should be pretty safe. Total physical memory of the device can be retrieved as described here while retrival of the available RAM can be derived from that question.
3) Maybe this is a good starting point. I would always write image data to the file system and just store the file name inside the database, as suggested here.
The iOS app I'm working on handles very large files (largest being 2.7 gig in size), and some sqlite tables, after downloading the large I'm getting console messages like this one :
Aug 24 14:50:28 unknown TheAppName[1407] <Warning>: Error opening database: 14 unable to open database file
Also other issues that happen, loading a view (which has already been loaded and presented) will cause a crash saying "nib cannot be located".
The app can run without the large file just fine, but it is very useful to have. The question I have is this : Is the large file causing some sort of memory issue, or is there some sort of limit that iOS places on files? I've looked around at other places and I've been unable to find anything specific to this.
Does it work in the Simulator or do you also have the same issue there?
I suggest you run your app using Instruments with the ObjectAlloc tool. Its likely you have some leaks in the way you are managing the download. Or, is there free space on the device for this file?
Others have had success with downloading huge files as long as sufficient space exists on the flash. You can test for this - there are a few functions floating around that tell you how to determine free disk space.
Another idea: write your file to the disk with the "F_NOCACHE" (fcntl) flag set on the file descriptor. This will cause the writes to bypass the "uniform buffer queue", which is used to cache disk blocks and for other memory uses, and will greatly reduce stress on the system itself.
An iOS app's max size limit is 2GB, this is limit is causing all the errors and is why your app is crashing. I would recommend you upload your large size files to a file hosting site and stream them into the app when you need them.
For a file on disk, is the Win32 function FlushFileBuffers as reliable and certain as closing the file using CloseHandle then re-opening the file using CreateFile?
Are there circumstances where CloseHandle then CreateFile are better because they save the data correctly to disk when FlushFileBuffers does not?
It is better, CloseHandle() doesn't flush the file system cache write buffers. Beware of the cost, it can take a long time to get the data to the disk. The FILE_FLAG_NO_BUFFERING option for CreateFile allows you to avoid flushing. But it is very expensive and difficult to get right due to the limitations on the written data.
According to the documentation, FlushFileBuffers does write everything to the disk. However, it probably doesn't hurt to test it yourself. I've done BRS testing (big red switch ... well PCs used to have big red switches) in the past, and I found that it did cause everything to be written. After the call to FlushFileBuffers, turn the PC off without a clean shutdown. Turn it back on and see if the data is all there. The behavior may change by OS (in theory it shouldn't ... but you never know). It was quite some time ago that I did tests like that (it was on XP or possibly even Windows 2000).
And I suppose it goes without saying, but you probably don't want to do this testing on a workstation that you really care about.
Although this information is not related to Delphi, but the most deployed SQL-database on earth, sqlite (used for example in Firefox) takes care on such things and you can read a lot ot atomic operations here: http://www.sqlite.org/atomiccommit.html
Below is a quote from the article about FlushFileBuffers
9.2 Incomplete Disk Flushes
SQLite uses the fsync() system call on
Unix and the FlushFileBuffers() system
call on w32 in order to sync the file
system buffers onto disk oxide as
shown in step 3.7 and step 3.10.
Unfortunately, we have received
reports that neither of these
interfaces works as advertised on many
systems. We hear that
FlushFileBuffers() can be completely
disabled using registry settings on
some Windows versions. ...