Slow responce from the SD card - android

I am working on application which will read the text file from the SD card and write its contents to other text file.
The implementation goes like this:
File result = new File("/mnt/sdcard/result.txt");
result .createNewFile();
FileWriter resultFileWriter = new FileWriter(result , true);
File f = new File("/mnt/sdcard/abc.txt");
BufferedReader mainBufferedReader =
new BufferedReader(new FileReader(f));
while((line = mainBufferedReader.readLine() ) != null)
{
lineNo ++
if(lineNo > 50 )
{
resultFileWriter .append(line);
resultFileWriter .append("\n");
resultFileWriter .flush();
}
}
resultFileWriter .close();
resultFileWriter = null;
mainBufferedReader .close();
mainBufferedReader = null;
The above code is working properly , but very few times ( 1 outof 20) it is taking much time do the above operation.
I suspect this is because of slow response from the SD card.
Please suggest me generally when there's chance to slow response from SD card.
or please let me know if there's any changes I need to do in my code.
Thanks.

As far as I remember this video is about such kind of delays:
http://developer.android.com/videos/index.html#v=c4znvD-7VDA
But the idea is to perform I/O operations asynchronously so these delays won't be able to slow down your UI.

Its better to use SQLITE DB. DB read/write is always faster than File I/O.

Related

Android UIAutomator - read textfile on sdcard during runtime

Is it possible to read a textfile on sdcard during runtime of an UIautomator test? As in an android application, using getExternalDirectory() etc. to create a File-object pointing to the actual file. Is it possible to send a command using getRuntime().exec("cmd"), if so, how? Or is there an easier way to simply access the device:s sdcard and read a file into the test?
The goal is to throughout the test send parameters to the test. So the test will perform certain actions, then continously look for a change on a file on the devices sdcard, and if so, read that line, and continue to perform actions. So therefor a way to read a file, and check certain things, is needed.
Or is there perhaps another way to pass information into the test during runtime? I know it can be done at the start of the testrun, but not during testrun.
I use below code inside uiautomator code to read text files.instead of
public void FileRead(String file_location) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(file_location));
try {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
String everything = sb.toString();
//you can do whatever you want here or return String
} finally {
br.close();
}
}

Android service file observer strange behavior

I need to implement a service in android that must be able to monitor a folder to detect a certain file and read what it contains. I'm having a strange behavior with my code and I can't find the reason. This is my relevant code.
public void onCreate(){
lectorFichCSV = new LectorFichCSV(); //object to read CSV files
ftpFileObserver = new FileObserver(filePath.getAbsolutePath()){
public void onEvent(int event, String file) {
if((FileObserver.CREATE & event) != 0){
Log.i("INFO: ", filePath.getAbsolutePath() + "/" + file + " is created");
if(file.substring(0,3).equals("RVE")){ //If file is created and the one I expect
try{
Log.i("INFO: ", "We have a RVE answer");
is = new FileInputStream(filePath + "/" + file);
lineaVent = lectorFichCSV.parseCSVFileAsList(is); //Get information in a list
//Get dao from ORMLite
dao = getHelper().getLineaVentDao();
Iterator<String[]> iterator = lineaVent.iterator();
if(iterator.hasNext()){
String[] aux = iterator.next();
Log.i("INFO:", "CodLineaVent "+aux[0]);
if(aux[2].equals("S")){
//Update DB information accordin to my file
UpdateBuilder<LineaVent, Integer> updateBuilder = dao.updateBuilder();
updateBuilder.where().eq("_id", aux[0]);
updateBuilder.updateColumnValue("valido", true);
updateBuilder.updateColumnValue("saldo", true);
updateBuilder.update();
lineaVent.clear();
}else if(aux[2].equals("N")){
UpdateBuilder<LineaVent, Integer> updateBuilder = dao.updateBuilder();
updateBuilder.where().eq("_id", aux[0]);
updateBuilder.updateColumnValue("saldo", false);
updateBuilder.update();
lineaVent.clear();
}
File fileToDel = new File(filePath + "/" + file);
fileToDel.delete();
}
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(SQLException e){
e.printStackTrace();
}
}
I debugged the code and sometimes is working and sometimes I get lineaVent.size() == 0. I'm going crazy with this, I'm thinking, is it possible that events occurs faster than the creation of my file? that would be the reason when I tried to parse my CSV file into my List object is size = 0? In that case I'm not getting any FileNotFoundException.
Any help will be appreciate. Thank you.
I am not an expert with the inotify POSIX API that, IIRC, underlies FileObserver. However, given that there are separate events for CREATE, MODIFY, and CLOSE_WRITE, it stands to reason that the CREATE event is solely for file creation -- in other words, allocating a new entry in the filesystem for the file. That would either create an empty file, or perhaps a file with some initial load of bytes, but where other MODIFY calls might be needed to write out the full contents. CLOSE_WRITE would then be called to indicate that whoever was writing to the file has now closed their file handle.
Hence, if you are watching for some file to be created, to read it in, watch for CREATE, then watch for CLOSE_WRITE on that same file, and then try to read it, and see if that works better.

Load strings.xml from sd card to application android

Is it possible to load strings.xml from sd card instead of application res/values/... Search on the web but didn't find any tutorials. My thought is download the xml to sd card then save the strings element to an array.
public void stringsxml(){
File file = new File(Environment.getExternalStorageDirectory()
+ ".strings.xml");
StringBuilder contents = new StringBuilder();
try {
//use buffering, reading one line at a time
//FileReader always assumes default encoding is OK!
BufferedReader input = new BufferedReader(new FileReader(file));
try {
String line = null; //not declared within while loop
/*
* readLine is a bit quirky :
* it returns the content of a line MINUS the newline.
* it returns null only for the END of the stream.
* it returns an empty String if two newlines appear in a row.
*/
while (( line = input.readLine()) != null){
contents.append(line);
contents.append(System.getProperty("line.separator"));
}
}
finally {
input.close();
}
}
catch (IOException ex){
ex.printStackTrace();
}
String data= contents.toString();
}
Well, actually it is semi-possible, but you have to create a derivate LayoutInflater which will replace string codes with thus read strings.
I have documented my attempts and failings together with initial implementation here.
Summary: simple strings work, string arrays do not
No, this is not possible. Check Android decoumentation about resources:
The Android SDK tools compile your application's resources into the application binary at build time. To use a resource, you must install it correctly in the source tree (inside your project's res/ directory) and build your application.
Resources are built-in into the application binary and you can't read them from a file.

Android memory error

I cannot understand why this keeps crashing with a memory error:
server = new URL("http://-link cannot be supplied-");
BufferedReader reader2 = read(server);
line = reader2.readLine();
StringBuilder bigString = new StringBuilder("");
while(line!=null) {
bigString.append(line);
reader2.readLine();
}
the file is not -that- big 7000 odd lines # 240,031 bytes on disk.
Basically what i need to do is to tell wether the file contains a small string (a postcode) the file is basically a list of postcodes.
What is the best way to read this in? as obviously what i am doing is not working at all :D
Your while loop never ends!
while(line!=null) {
bigString.append(line);
line = reader2.readLine();
}
should work.

Problem finding/reading a file

I'm trying to develop a small application, where I was given a JSON file, and I have to extract data from it. As I understood a JSON object takes a string argument, thus I'm trying to access a file and write the data from it to a string.
I've placed that file in a "JSON file" folder, and when I try to read the file, it throws me a file not found exception.
I've tried several ways to find a path to that file, but every attempt was for vain.
It might be that I'm extracting the path wrong, or might be something else, please help me.
Thanks in advance.
here is the code of finding the path:
try
{
path = Environment.getRootDirectory().getCanonicalPath();
}
catch (IOException e)
{
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
File jFile = new File(path + /"JSON file/gallery.json");
here is the code for reading from a file :
String str ="";
try
{
BufferedReader in = new BufferedReader(new FileReader(jFile));
while ((str += in.readLine()) != null)
{
}
in.close();
}
catch (IOException e)
{
e.getMessage();
}
return str;
Here more specification:
I want to take the data from the file in order to do that : JSONObject(jString).
when I extract the path of json file I create a file with the path and pass it to the function that reads from the file, and there it throws me a file not found exception, when I try to read from it.
The file does exists in the folder (even visually - I've tried to attach an image but the site won't let me, because I'm new user)
I've tried to open the file through the windows address bar by typing the path like that:
C:\Users\Marat\IdeaProjects\MyTask\JSON file\gallery.json and it opens it.
if you store it in the assets folder you can access it by using
InputStream is = context.getResources().getAssets().open("sample.json");
You can then convert it to a String
public static String inputStreamAsString(InputStream stream)
throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(stream));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
return sb.toString();
}
EDIT
You need to put the file in the device, if it is on your computer, it is not accessible from your device. There are some ways to do that, and one of them is to put it in the res/ dir of your application. Please refer to the documentation to see how to do that.
Debug it. I'm pretty sure it will be very easy to find. To start with, look for the following:
Print the path before you create the file, e.g. Log.d("SomeTag", path + "/JSON file/gallery.json")
Observe the full exception details. Maybe there is another problem.
Explore the folders and see if the file exists (in eclipse: window -> show view -> other -> android -> file explorer.
You will probably observe the problem and be able to fix it. If not, post here a question with more details, including the results of those trials.
BTW, GetgetRootDirectory() returns the root directory of android, that's not what you want (you don't have RW permissions there) you probably want to get the applcation directory, you can see how to get it here, in the question I asked a few month ago. But since you didn't give us those details, it will be hard to help you more then that.

Categories

Resources