Using the scanner class to parse a file but it takes far too long to run
I have a file containing around 39000 ints seperated by commas with 13 ints on each line so i set up a file reader and a scanner to read and parse it however it litterally takes over an hour to run. I think I probably need to use a bufferedreader but not sure how to implement it. Can anybody suggest a better (faster) way of doing this?
Here's my code:
public class ECGFilereader { // reads the ecg files from the SD card
public final static int numChannels = 12; // the data is stored in 12 channels, one for each lead
public final static int numSamples = 3000; //500 = fs so *6 for 6 seconds of data
private File file;
private Scanner scanner;
short [] [] ecg = new short [numChannels] [numSamples]; //Creates a short called ecg in which all of the samples for each channel lead will be stored
public ECGFilereader (String fname) throws FileNotFoundException
{
file = new File(Environment.getExternalStorageDirectory() +"/1009856.txt"); //accesses the ecg file from the SD card
scanner = new Scanner(file);
开发者_运维技巧
scanner.useDelimiter(",|\\r\\n"); //sets commas and end's of lines as separators between each int
}
public boolean ReadFile(Waveform[] waves) // sorts data into and array of an array (12 channels each containing 3000 samples)
{
for (int sample=0; sample<numSamples && scanner.hasNextInt(); sample++) //
{
scanner.nextInt();
for (int chan = 0; chan<numChannels; chan++)
{
if(scanner.hasNextInt())
ecg [chan] [sample] = (short) scanner.nextInt();
else if (scanner.hasNextLine())
{ scanner.nextLine();
}
else return false;
}
}
for (int chan=0; chan<numChannels; chan++)
waves[chan].setSignal(ecg[chan]); // sets a signal equal to the ecg array of samples for each channel
return true;
}
}
EDIT:
I have now removed the scanner class completely and it works perfectly with the following code:
public boolean ReadFile(Waveform[] waves) // sorts data into and array of an array (12 channels each containing 3000 samples)
{
try {
BufferedReader in = new BufferedReader(new FileReader(file));
String reader = "";
for (int sample=0; sample<numSamples; sample++){
if ((reader = in.readLine()) == null) {
break;}
else {
String[] RowData = reader.split(","); // sets the commas as separators for each int.
for (int chan=0; chan <12 && chan<RowData.length; chan++)
ecg [chan][sample]= Integer.parseInt(RowData[chan+1]); //parses each int from the current row into each channel for the ecg[]
}
}
in.close();
} catch (IOException e) {
}
for (int chan=0; chan<numChannels; chan++)
waves[chan].setSignal(ecg[chan]); // sets a signal equal to the ECG array of samples for each channel
return true;
}
}
Are you sure that your delay is coming from the Scanner and not the final setSignal loop you put in?
I would recommend using TraceView to figure out exactly where your program is hanging up. It helped me greatly with a similar problem.
Let me know if this helps. I suggest putting the start and stop points at the beginning and end of the first loop. Like this:
public class ECGFilereader { // reads the ecg files from the SD card
public final static int numChannels = 12; // the data is stored in 12 channels, one for each lead public final static int numSamples = 3000; //500 = fs so *6 for 6 seconds of data private File file; private Scanner scanner; short [] [] ecg = new short [numChannels] [numSamples]; //Creates a short called ecg in which all of the samples for each channel lead will be stored
public boolean ReadFile(Waveform[] waves) // sorts data into and array of an array (12
channels each containing 3000 samples)
{
Debug.startMethodTracing("scanner");
for (int sample=0; sample<numSamples && scanner.hasNextInt(); sample++) //
{
scanner.nextInt();
for (int chan = 0; chan<numChannels; chan++)
{
if(scanner.hasNextInt())
ecg [chan] [sample] = (short) scanner.nextInt();
else if (scanner.hasNextLine())
scanner.nextLine();
else return false;
}
}
Debug.stopMethodTracing();
Debug.startMethodTracing("setSignal");
for (int chan=0; chan<numChannels; chan++)
waves[chan].setSignal(ecg[chan]);
// sets a signal equal to the ecg array of samples for each channel
Debug.stopMethodTracing();
return true;
}
This way you will have 2 traceView files to analyze to see where your performance issues are coming from.
EDIT:
One other thing you need to make sure you're doing is checking if the external storage is available. Do that with the following code:
boolean mExternalStorageAvailable = false;
boolean mExternalStorageWriteable = false;
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
// We can read and write the media
mExternalStorageAvailable = mExternalStorageWriteable = true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
// We can only read the media
mExternalStorageAvailable = true;
mExternalStorageWriteable = false;
} else {
// Something else is wrong. It may be one of many other states, but all we need
// to know is we can neither read nor write
mExternalStorageAvailable = mExternalStorageWriteable = false;
}
精彩评论