Campin Carl
Campin Carl

Reputation: 121

Problems reading from .txt file Java

So I've developed a system that saves database insert/update commands into a text file whenever a user tries to save and the database connection isn't there. Each line in the file is one insert or update command. However, I seem to have run into a problem.

Some of the files seem to not want to read passed the first line. All of them have one thing in common-since there is data in the database that corresponds to the first insert, I skip it as that information is not allowed to change once entered. However, when I go to try to read the next line, it boots out because the readLine() command returns null (which causes the rest of the code to fail as intended).

I have tried adding a while(!ready() Thread.sleep(500)) before the next readLine(), but it just sits there indefinitely (I let it go for about ~10 minutes before killing the JVM). I have also tried just adding an else block to the if that checks for the data being present in the database, which pauses for 2 seconds, but the problem persisted.

Note that any file which starts with an insert for data that is NOT present works just fine.

Does anyone have any ideas on how to solve this problem?

Edit: Here's the code from top to the wait for ready

private static boolean loadExistingData()
{
    File dir = new File(Configuration.DBOutputDataLocation);
    // Attempt to create the directory in case it doesn't exist.
    if(!dir.exists())
    {
        if(!dir.mkdir())
        {
            return false;
        }
    }
    String[] existingFiles = dir.list();
    System.out.println(existingFiles.length);
    if(existingFiles == null || existingFiles.length == 0)
    {
        return false;
    }
    else
    {
        BufferedReader fileReader = null;
        DatabaseAccessor dba = DatabaseAccessor.getInstance();
        // Pull out the files, submit each one.
        for(int i = 0; i < existingFiles.length; i++)
        {
            try
            {
                fileReader = new BufferedReader(new FileReader(new File(Configuration.DBOutputDataLocation + existingFiles[i])));
            }
            catch(FileNotFoundException e)
            {
                System.err.println("ERROR Reading From File: " + existingFiles[i]);
                e.printStackTrace();
            }
            // Recreate much of Util.saveToDB();
            if(dba.isConnected())
                dba.disconnect();
            if(!dba.connect(Configuration.dbUser, Configuration.dbPass, Configuration.dbURL))
                return false;
            String sqlUpdate;
            String serialNum = "";
            int testNum;
            /**
             * Sensor Information {serial number, type, capacity, etc.} Data
             */
            try
            {
                // Read Line for the Sensor data.
                sqlUpdate = fileReader.readLine();
            }
            catch(IOException e)
            {
                System.err.println("ERROR Reading From File: " + existingFiles[i]);
                e.printStackTrace();
                try
                {
                    fileReader.close();
                }
                catch(IOException e1)
                {
                    e1.printStackTrace();
                }
                return false;
            }
            try
            {
                int serialNumBegin = sqlUpdate.indexOf("'") + 1;
                int serialNumEnd = sqlUpdate.indexOf("'", serialNumBegin);
                serialNum = sqlUpdate.substring(serialNumBegin, serialNumEnd);
                System.out.println("Sensor sqlUpdate: " + sqlUpdate);
                if(!dba.contains("sensor", "serial_number = '" + serialNum + "'"))
                {
                    try
                    {
                        // please work, please work, please work...
                        dba.executeUpdate(sqlUpdate);
                    }
                    catch(SQLException e)
                    {
                        // gaa! ok, give user moderately descriptive error. What could
                        // they do about it anyway? Reconfigure the SQL server?
                        e.printStackTrace();
                        System.out.println("failed sensor entry @ update");
                        try
                        {
                            fileReader.close();
                        }
                        catch(IOException e1)
                        {
                            e1.printStackTrace();
                        }
                        return false;
                    }
                }
                else
                {
                    System.out.println("Sensor Exists, skipping.");
                }
            }
            catch(SQLException e1)
            {
                e1.printStackTrace();
                System.out.println("failed sensor entry");
                try
                {
                    fileReader.close();
                }
                catch(IOException e2)
                {
                    e1.printStackTrace();
                }
                return false;
            }
            /**
             * Sensor Test xref
             */
            try
            {
                int k = 0;
                while(!fileReader.ready())
                {
                    Thread.sleep(500);
                    System.out.println("Slept : " + k++);
                }
            }
            catch(IOException e3)
            {
                e3.printStackTrace();
            }
            catch(InterruptedException e)
            {
                // TODO Auto-generated catch block::: Problem with file not being
                // ready!!111oneoneoneeleventyeleven
                e.printStackTrace();
            }
            try
            {
                // Read Line for the Sensor test data.
                sqlUpdate = fileReader.readLine();
            }
            catch(IOException e)
            {
                System.err.println("ERROR Reading From File: " + existingFiles[i]);
                e.printStackTrace();
                try
                {
                    fileReader.close();
                }
                catch(IOException e1)
                {
                    e1.printStackTrace();
                }
            }
            System.out.println("Sensor Test Xref: " + sqlUpdate);
            // Locate the test number
            int serialNumBegin = sqlUpdate.indexOf("'") + 1;
            int serialNumEnd = sqlUpdate.indexOf("'", serialNumBegin);
            int testNumBegin = serialNumEnd + 2;
            int testNumEnd = sqlUpdate.indexOf(",", testNumBegin);
            testNum = Integer.parseInt(sqlUpdate.substring(testNumBegin, testNumEnd));
            if(testNum == -1)
            {
                // increments until it finds an unused test #
                try
                {

                    while(dba.contains("sensor_test_xref", "serial_number = '" + serialNum + "' and test_no = " + (++testNum)));
                }
                catch(SQLException e1)
                {
                    e1.printStackTrace();
                    JOptionPane.showMessageDialog(new JFrame(), "Error saving test information (date, test number, station...) to database",
                            "DB Error", JOptionPane.ERROR_MESSAGE);
                    System.out.println("failed sensor_test_xref");
                    try
                    {
                        fileReader.close();
                    }
                    catch(IOException e2)
                    {
                        e1.printStackTrace();
                    }
                    return false;
                }

                System.out.println("settled on test# " + testNum);

                // Splice test number back in
                // Gets me the beginning up to the comma before the test number
                String firstPartOfUpdate = sqlUpdate.substring(0, testNumBegin);
                // Gets me the last part of it, from the comma to the end.
                String lastPartOfUpdate = sqlUpdate.substring(testNumEnd);
                // Piece everything back together...
                sqlUpdate = firstPartOfUpdate + testNum + lastPartOfUpdate;
                try
                {
                    dba.executeUpdate(sqlUpdate);
                }
                catch(SQLException e)
                {
                    e.printStackTrace();
                    // obviously a good entry was not made
                    testNum = -1;
                    System.out.println("failed sensor_test_xref");
                    try
                    {
                        fileReader.close();
                    }
                    catch(IOException e1)
                    {
                        e1.printStackTrace();
                    }
                    return false;
                }
                System.out.println("sensor_test_xref success");
            }
            /**
             * Temperature Point Data.
             */
            try
            {
                // Need a loop because there should be one line for each temp. point.
                while(fileReader.ready())
                {
                    try
                    {
                        sqlUpdate = fileReader.readLine();
                    }
                    catch(IOException e)
                    {
                        System.err.println("ERROR Reading From File: " + existingFiles[i]);
                        e.printStackTrace();
                        try
                        {
                            fileReader.close();
                        }
                        catch(IOException e1)
                        {
                            e1.printStackTrace();
                        }
                        return false;
                    }

                    // Locate the temp point
                    int serialNumBegin1 = sqlUpdate.indexOf("'") + 1;
                    int serialNumEnd1 = sqlUpdate.indexOf("'", serialNumBegin1);
                    int testNumBegin1 = serialNumEnd1 + 2;
                    int testNumEnd1 = sqlUpdate.indexOf(",", testNumBegin1);
                    int tempPointBegin = testNumEnd1 + 2;
                    int tempPointEnd = sqlUpdate.indexOf("'", tempPointBegin);
                    String tempPoint = sqlUpdate.substring(tempPointBegin, tempPointEnd);
                    // the unique key for a temperature point entry
                    String condition =
                            "serial_number = '" + serialNum + "' and test_no = " + testNum + " and temp_point = '" + tempPoint + "'";
                    // if an entry already exists delete it
                    try
                    {
                        if(dba.contains("sensor_temp_point", condition))
                        {
                            try
                            {
                                dba.executeUpdate("delete from sensor_temp_point where " + condition);
                            }
                            catch(SQLException e)
                            {
                                e.printStackTrace();
                                try
                                {
                                    fileReader.close();
                                }
                                catch(IOException e1)
                                {
                                    e1.printStackTrace();
                                }
                                return false;
                            }
                        }
                    }
                    catch(HeadlessException e1)
                    {
                        e1.printStackTrace();
                        try
                        {
                            fileReader.close();
                        }
                        catch(IOException e2)
                        {
                            e1.printStackTrace();
                        }
                        return false;

                    }
                    catch(SQLException e1)
                    {
                        e1.printStackTrace();
                        try
                        {
                            fileReader.close();
                        }
                        catch(IOException e2)
                        {
                            e1.printStackTrace();
                        }
                        return false;

                    }

                    // Splice test number and temperature point back in
                    // Gets me the beginning up to the comma before the test number
                    String firstPartOfUpdate = sqlUpdate.substring(0, testNumBegin1);
                    // Gets me the last part of it, from the comma to the end.
                    String lastPartOfUpdate = sqlUpdate.substring(tempPointEnd);
                    // Piece everything back together...
                    sqlUpdate = firstPartOfUpdate + testNum + ",'" + tempPoint + lastPartOfUpdate;

                    System.out.println("Temp Point sqlUpdate: " + sqlUpdate);
                    try
                    {
                        dba.executeUpdate(sqlUpdate);
                    }
                    catch(Exception e)
                    {
                        e.printStackTrace();
                        System.out.println("failed to save temp. point data : " + i);
                        try
                        {
                            fileReader.close();
                        }
                        catch(IOException e1)
                        {
                            e1.printStackTrace();
                        }
                        return false;
                    }

                }
            }
            catch(IOException e)
            {
                System.err.println("ERROR Reading From File: " + existingFiles[i]);
                e.printStackTrace();
                try
                {
                    fileReader.close();
                }
                catch(IOException e1)
                {
                    e1.printStackTrace();
                }
                return false;
            }
            System.out.println("all successful");
            // Close the file before deletion!
            try
            {
                fileReader.close();
            }
            catch(IOException e1)
            {
                e1.printStackTrace();
            }
            try
            {
                new File(Configuration.DBOutputDataLocation + existingFiles[i]).delete();
            }
            catch(SecurityException e)
            {
                e.printStackTrace();
            }

        }
        System.out.println("All Files Saved Successfully.");
        dba.disconnect();

        return true;
    }
}

And here's another edit for a sample file. I cut out the data portions to save space and only included one 'sensor_temp_point' line (there are 4 in the file).

insert into sensor (serial_number, sensor_type, amplification_id, sensor_max_capacity,  unit_cd) values ;
insert into sensor_test_xref (serial_number, test_no, test_station, test_date, tester_initials, test_load) values ;
insert into sensor_temp_point (serial_number, test_no, temp_point, temp_val, excitation_val, linearity, temp_zero_shift_abs, temp_span_shift_abs, load_0_actual_val, load_0_raw_val, load_0_norm_val, load_50_actual_val, load_50_raw_val, load_50_norm_val, load_100_actual_val, load_100_raw_val, load_100_norm_val, load_0r_actual_val, load_0r_raw_val, load_0r_norm_val, last_reading_time) values ;

Upvotes: 2

Views: 3780

Answers (3)

Raedwald
Raedwald

Reputation: 48674

while(!ready() Thread.sleep(500))

If I understand you correctly, you are trying to say that your want your code to read the text file concurrently with the process (or thread) that is writing to the file? If so, that could be the problem you have.

When a program issues a write() to a file, the output is very likely to be buffered somewhere. The buffered data will not be written into the real file until the program flush()-es of close()-es its output file. You might therefore need to look at the other program, which writes the data you want to read.

When one program is to read data concurrently with a program that writes that data, the two programs must have some concurrency control. On Unix (POSIX) systems, programs that communicate in that manner usually use a pipe rather than a file, and the functionality for handling blocking I/O provides the concurrency control. Things are trickier when you want to use a file. Your reading program could try polling until it reads a distinctive pattern that indicates the end of the text. You could use a locking scheme, so the file is locked until the writer has finished writing to the file.

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1500485

readLine() will return null when it reaches the end of the file. There's no point in waiting to read again - you should just stop at that point.

EDIT: Okay, now the code is up - you really need to refactor this. It's pretty much unreadable at the moment. Split it into smaller methods, and close the file reader in a finally block instead of in the vast number of places you're currently doing it.

It's not clear exactly what's going on, but generally to loop through the contents of a file, I would use:

String line;
while ((line = reader.readLine()) != null)
{
    // Use the line
}

When readLine returns null, that means there's no more data. I wouldn't use ready() at all.

Once you've refactored your code (just using a finally block for closing the file will remove about a quarter of the method - then refactor it further) it'll be a lot easier for you to work out what's really going on.

Upvotes: 27

Speck
Speck

Reputation: 2309

Whenever I need to read a file I do a google search for "java read text file". (a good practice for many tasks you don't want to remember how to do.) There are many pages out there that show basic techniques for reading text files.

Here is one. http://www.javapractices.com/topic/TopicAction.do?Id=42

Upvotes: 2

Related Questions