Fourteenth example Purpose: Many applications need a permanent storage area for a large amount of varying information or for saving data that must survive when the program ends. The J2ME Midlet class library provides a storage mechanism for a small amount of data, the Record Management System (RMS). Larger amount of data should be stored as data files on one of the mobile phone's memory chip, which can be a build-in or additional flash memory. To access the file system, the mobile phone must support the File Connection package, as defined by the JSR 75 (Java Specification Request). Most modern devices conform to JSR 75. As usual, file input-output is a cumbersome matter and cost lot of experience, time and nerves. In Java file-IO uses the stream classes. Because streams allocate system resources, a stream must be "opened", "used" and "closed" again. The class MFile is part of the Gidlet framework and simplifies the IO considerably, because file operations can be done without explicitly using streams. The idea behind is simple (inspired by the class CPPath of the C++/Champ framework): Like for the class File in J2SE each instance of MFile is an abstraction of the fully qualified file path. File manipulations and operations are implemented as methods of the MFile class, but more than this, all stream operations are transparent to the user of the MFile class. As example, the following code creates a text file and appends to lines: MFile mf
= new MFile("c:/Photos/Info.txt"); For testing and demonstration purposes the MConsole is very well suited, because lines can be displayed in the System.out.println() manner. The following program creates the file too.txt in the root named root1 and appends 3 lines of text each time it is run. // FileAppendGidlet.java Discussion: The root named root1/ corresponds to the simulated file system root when using the emulator. You find root1 as subdirectory in the following directory: For WTK 2.5.2: <userhome\>j2mewtk\2.5.2\appdb\DefaultColorPhone\filesystem After running the program, you can look for the file foo.txt in the directory root1 and check its content by opening it with any text editor. Each time the program runs, 3 more lines are appended. If you use write() instead of append(), the current content is cleared before the new data is written. It's somewhat annoying to get a security message each time the emulator's file system is accessed. To suppress the question that the emulator ask about accessing the file system change in file c:\Documents and Settings\\j2mewtk\2.5.2\appdb\_policy.txt The warning message can be suppressed on the real mobile phone by signing the Midlet or, on same devices, by selecting the Rights property in the Midlets soft button menu accordingly. When the emulator uses the file system, it creates a tag file in.use in directory DefaultColorPhone. In some circumstances this file in not deleted when the emulator terminates and later file operations fail. If you have problems with file operation, check for this tag file and delete it by hand.
Fifteenth example Purpose: With MFile it's very easy to read the previously written file and display its content.
Execute FileReadGidlet (if you have the Sun's Wireless Toolkit (WTK) installed and the JAD extension registered. Learn how to register the JAD extension) Discussion: append(), write() and read() work with text files only. If you want to store some other primitive data types, you must either convert them to strings or use your own DataInputStream and DataOutputStream. There are examples how to do this in the Gidlet distribution.
Sixteenth example Purpose: In some circumstances you want to get a list all files and/or directories in a certain directory. The MFile class uses findFirst() and findNext() to perform this task.
Execute FileEnumerateGidlet (if you have the Sun's Wireless Toolkit (WTK) installed and the JAD extension registered. Learn how to register the JAD extension) Discussion: The procedure for using findFirst() and findNext() is the following:
Be aware that findFirst() and findNext() have a side effect by modifying the MForm's path to the file/directory that was found. We use the emulator's root root1/ again. (For the real device, you must use the root names for your device. You may try with c:/ or enumerate all available roots by using the same technique with findFirstRoot() and findNextRoot() respectively. Execute RootEnumerateGidlet, source included in Gidlet distribution) At the end we display the space used for of all files in the root directory and its subdirectories. Then we also display the remaining free space in the file system. Sometimes it is convenient to retrieve a directory path from the following properties: fileconn.dir.photos For example, to get all files and subdirectories where are the photos, call String photoDir = System.getProperty("fileconn.dir.photos"); and strip the URL part file:/// before instantiating the MFile: MFile mf = new MFile(photoDir.substring(8)); Then apply the code in FileEnumerateGidlet. If the specific directory is not available, getProperty() returns null.
Seventeenth example Purpose: With MFile it is straightforward to perform file operations like creating/removing directories and files. The following examples show same of these manipulations. We first look for a certain directory. If it already exists, we are cautious not to change existing data. So we quit. (To run the program successfully, either delete the directory with a file explorer or select another directory name.) Next we create the directory, and also create an empty file in this directory. Then we try to remove the directory, but this fails, because it is not empty. So we delete the file and finish by removing the directory successfully.
Execute FileCreateGidlet (if you have the Sun's Wireless Toolkit (WTK) installed and the JAD extension registered. Learn how to register the JAD extension) Discussion: Because MFile's methods do not throw exceptions, it is a common technique to check return values for success or failure. Instead of creating a new instance of MFile each time you need another path, use setPath() to modify the current path. We use a special constructor for MConsole to set the background color, the text color and the text size to our preference. Eighteenth example Purpose: With MFile's read/write-methods you always transfer the whole content of the file to/from a string. This can exhaust the memory if the file is very big. In this case you better use the traditional stream approach. In addition, you can store the primitive data types without converting them to strings when using the DataInputStream and DataOutputStream. In the following example we store 10 integers and read them back.
Execute FileStreamGidlet (if you have the Sun's Wireless Toolkit (WTK) installed and the JAD extension registered. Learn how to register the JAD extension) Discussion: | ||||||||||