290 likes | 390 Views
Data Storage, Continued. Review of FileConnection. Can read data that other apps have written to file system A traditional file system javax.microedition.io.file package Use Connector class to create the actual connection. Review Connector Class. javax.microedition.io.Connector
E N D
Review of FileConnection • Can read data that other apps have written to file system • A traditional file system • javax.microedition.io.file package • Use Connector class to create the actual connection Wendi Jollymore, ACES
Review Connector Class • javax.microedition.io.Connector • A factory class used to create connections • File connections, network connections, etc.. • Connector.open(string) • opens a connection and returns a Connection object • {scheme}:[{target}][{parms}] (see docs for a list of schemes) • {scheme} - name of a protocol, such as http:// or file:// • {target} - normally some kind of network address or resource • Any {parms} are formed as a series of equates of the form ";x=y". i.e. ";type=a“ Wendi Jollymore, ACES
Review File System • It’s important to know the locations of the various storage locations: • store/ • device memory home - internal flash memory • SDCard/ • sd card home • system/ • internal sd card on Bold and Storm (transient data objects and runtime processes - 860MB) Wendi Jollymore, ACES
Review Creating Connection • Exception is thrown if path is invalid • Doesn’t have to exist - *could* exist • Only the last item can be non-existent • This allows you to create new files/directories try { FileConnection storeDirectory = FileConnection)Connector.open("file:///store/"); } catch (IOException e) { Dialog.alert(e.getMessage()); } Wendi Jollymore, ACES
Review FileConnection Methods • FileConnection.close() • From parent interface Connection • Closes file connection • FileConnection.isDirectory() • True if the object points to a directory • FileConnection.exists() • True of the directory/file exists Wendi Jollymore, ACES
FileConnection Methods • FileConnection.create() • Creates a file corresponding to the string provided in the Connection.open() method • Created with 0 length • Does not create directories in the path • Throws IOException • Use output streams to write data to the file Wendi Jollymore, ACES
FileConnection Methods • FileConnection.mkdir() • Creates a directory corresponding to the string provided in the Connection.open() method • Not recursive – you must create all new dirs in a path if they don’t exist • throws IOException Wendi Jollymore, ACES
Working with Dirs and Files • If you have a file that doesn’t exist in a directory that doesn’t exist • You have to create the directory first: • FileConnection fileConn = • (FileConnection) Connector.open(aPath); • if (!fileConn.exists()) { • fileConn.mkdir(); • } Wendi Jollymore, ACES
Working with Dirs and Files • Then you have to reset the file connection: • Then you have to create a connection to the file and create it: fileConn.close(); fileConn = null; fileConn = (FileConnection) Connection.open(fileName); if (!fileConn.exists()) { fileConn.create(); } Wendi Jollymore, ACES
Working with Dirs and Files • If your directory and file already exist, there’s a shorter way: • This still allows you to use the same FileConnection object • But it only works when every part of the path/file exists • Throws an IOException fileConn.setFileConnection(fileName); Wendi Jollymore, ACES
Working with Streams • To read and write data, you need an input or output stream • We use binary steams only • more efficient • can use regular InputStream or OutputStream • DataInputStream or DataOutputStream a bit more convenient • you can read/write data types and strings (sort of) Wendi Jollymore, ACES
Working with Streams • FileConnection.openInputStream(); • Opens and returns an InputStream object • Connected to the file specified when the connection was created • The file must exist, must be accessible • FileConnection.openDataInputStream(); • Opens and returns a DataInputStream object • Same as above • Both throw IOException Wendi Jollymore, ACES
Working with Streams • FileConnection.openOutputStream(); • Opens and returns an OutputStream object • File pointer positioned at start of file • The file must exist, must be accessible • openOutputStream(long offset) will start at byte offset • FileConnection.openDataOutputStream(); • Opens and returns a DataOutputTream object • Same as above but can’t use offset • All throw IOException Wendi Jollymore, ACES
Working with Streams • Opening streams from the file connecton object: • When you are done with a stream: • Close it using close() method • Assign null to stream object DataInputStream fileIn = fileConn.openDataInputStream(); DataOutputStream fileOut = fileConn.openDataOutputStream(); Wendi Jollymore, ACES
Working with Streams • Look up DataInputStream and DataOutputStream in the api docs • Note the methods to read and write data to the file • Everything must be a fixed size • E.g. ints are always 4 bytes, doubles are 8 bytes, Strings are 2 bytes per character • Remind you of Random Access Files? Wendi Jollymore, ACES
Working with Streams • Strings are the ones you need to pay most attention to. • When storing data as “records”, all records must be exact same size • So you know where to find record x • All strings must be fixed width • Define how many characters your string fields are • Make sure they’re saved as that exact size Wendi Jollymore, ACES
Working with Streams • Example: Field size is 25 • Field is either truncated or padded to be the exact size of 25 chars • int currSize = str.length(); • if (currSize > size) • str = str.substring(0, size); • else if (currSize < size) { • String temp = str; • for (int i=currSize; i<=size; i++) • str += “ “; • } Wendi Jollymore, ACES
Working with Streams • Example: reading back the same data • Read individual chars until you build the string field • Must be the correct number of chars! String temp = “”; for (int i=0; i<size; i++) { String c = String.valueOf(fileIn.readChar()); temp += c; } Wendi Jollymore, ACES
Exercise • New Program • Add three EditFields • One to enter an int, one for a double, and one for a String • Add buttons Save, Clear, Read • Add event handling stuff for buttons • Add a display label • Save: saves the 3 values • Info: clears txt fields • Read: shows some saved values Wendi Jollymore, ACES
Exercise • We’ll set the string to 25 chars • A whole record will be 62 bytes • 4 for the int, 8 for the double • 25 * 2 for the string • We’ll need methods: • Prep the string for writing • Read the string from a stream • Add the same loadFile() method • Display file size in label, too Wendi Jollymore, ACES
Exercise • Saving Data method: fileDataOut() • Use the file connection to create a DataOutputStream • writeInt(), writeDouble() • Prep the string value and writeChars() • Close stream and set to null Wendi Jollymore, ACES
Exercise • Reading Data method: fileDataIn() • Calc number of records • File size / rec size • If the file connection is readable and we have records: • Create a DataInputStream • For each record: • readInt(), readDouble(), your readString() method • Build an output string • Close stream and set to null • Display output from file in label Wendi Jollymore, ACES
Exercise • When program exits, you must: • Close file connection • Assign null to file connection object • Override the close() method: if (fileConn != null && fileConn.isOpen()) { fileConn.close(); fileConn = null; } Wendi Jollymore, ACES
Simulator Notes • If you want to start from scratch each time you debug: • Erase File System option • Be careful doing this if you’re using SDCard option!! Wendi Jollymore, ACES
File Issues • What happens when you run the app multiple times? • Add new data each time • What happens to your old data? • You can’t append with DataOutputStream • You must use OutputStream • Set the offset to the file size Wendi Jollymore, ACES
File Issues • Example: long size = fileConn.fileSize(); OutputStream fileOut = fileConn.openOutputStream(size); • Also: • OutputStream works with data differently • There are no methods like writeInt() • You have to convert ints and doubles to bytes! Wendi Jollymore, ACES
File Issues • Converting ints and doubles to bytes: • I gave you some code in the notes • Note that strings are no longer 2 bytes per character • They’re one byte each • You’ll need to adjust your read method • You’ll need to adjust any size constants • String.getBytes() returns byte[] Wendi Jollymore, ACES
Exercise • Edit your program so that you can append records to the end of the file • String.getBytes() will give you the bytes for the String value • outputStream.write(byte[]) will write an array of bytes • dataInputStream.readFully(byte[]) can be used to read your string data back • Then String s = new String(bytes); Wendi Jollymore, ACES