I recently worked on a J2ME application and had to read and write files to the filesystem. Now for reading files, most of the articles I found online told you how to read files that were in the 'res' folder of the application. But this method, for some reason, doesn't work for reading files from the file system. After much browsing, I finally found a way to to it. Here are the two functions,
//Function to read file in the 'res' folder of the application
private String readResourceFile(String filename) {
try {
Reader in = new InputStreamReader(this.getClass().getResourceAsStream(filename), "UTF8");
StringBuffer sbuffer = new StringBuffer(1024);
char[] buffer = new char[1024];
int chars, i = 0;
while ((chars = in.read(buffer, 0, buffer.length)) != -1) {
sbuffer.append(buffer, 0, chars);
}
return sbuffer.toString();
} catch (Exception e) {
return "Failed to read file.";
}
}
//Function to read file from filesystem
private String readFile(String filename) {
try {
FileConnection fc = (FileConnection)
Connector.open(filename, Connector.READ);
if(!fc.exists()) {
throw new IOException("File does not exist");
}
InputStream is = fc.openInputStream();
int ch;
StringBuffer sbuffer = new StringBuffer(1024);
while ((ch = is.read()) != -1) {
sbuffer.append((char)ch);
}
return sbuffer.toString();
} catch (Exception e) {
return "Failed to read file.";
}
}Now the parameter to the first function will be just the name of the file in the 'res' folder, while the parameter to the second function will be the complete path of the file, for example, call
readResourceFile('file.txt');
readFile('file:///E:/file.txt');
Also, readFile() only works for the files on the memory card. Trying to read files in 'C:' would lead to an error, I assume because of insufficient permissions.
Writing to file is quite straightforward, the only quirk being that again I could write to the memory card, but not to 'C:'.
//Function to write file to the filesystem. Example use, 'writeFile('file:///E:/file.txt')'
private boolean writeFile(byte[] data, String filename) {
Connection c = null;
OutputStream os = null;
try {
c = Connector.open(filename, Connector.READ_WRITE);
FileConnection fc = (FileConnection) c;
if (!fc.exists())
fc.create();
else
fc.truncate(0);
os = fc.openOutputStream(fc.fileSize());
os.write(data);
os.flush();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
try {
if (os != null)
os.close();
if (c != null)
c.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Also, if you want to download a large file over HTTP, using the HTTP library gives some problems. For large files, http.getLength() returns -1, even when the data has been downloaded. Using a buffered reader to read this data doesn't work well as well. The best way to do this is
//Download a large file over http
private String downloadFile() throws IOException {
StreamConnection c = null;
InputStream s = null;
try {
c = (StreamConnection)Connector.open(url);
s = c.openInputStream();
int ch;
StringBuffer sbuffer = new StringBuffer(1024);
while ((ch = s.read()) != -1) {
sbuffer.append((char)ch);
}
return sbuffer.toString();
} finally {
if (s != null)
s.close();
if (c != null)
c.close();
}
}
Accessing the filesystem was the most frustrating part of coding with coding with J2ME, the rest is fun. Have fun with it.
Sunday, September 5, 2010
Subscribe to:
Comments (Atom)