Проблемы с чтением из .txt файла Java - PullRequest
2 голосов
/ 22 марта 2011

Итак, я разработал систему, которая сохраняет команды вставки / обновления базы данных в текстовый файл всякий раз, когда пользователь пытается сохранить, а соединение с базой данных отсутствует.Каждая строка в файле - одна команда вставки или обновления.Тем не менее, я, кажется, столкнулся с проблемой.

Некоторые файлы, по-видимому, не хотят читать после первой строки.У всех них есть одна общая черта - поскольку в базе данных есть данные, соответствующие первой вставке, я пропускаю их, поскольку эта информация не может изменяться после ввода.Однако, когда я пытаюсь прочитать следующую строку, она загружается, потому что команда readLine() возвращает ноль (что приводит к сбою остальной части кода, как и предполагалось).

Я пытался добавить while(!ready() Thread.sleep(500)) до следующего readLine(), но он просто сидит там бесконечно (я оставляю его на ~ 10 минут, прежде чем убить JVM).Я также попытался просто добавить блок else в if, который проверяет наличие данных в базе данных, что делает паузу на 2 секунды, но проблема сохраняется.

Обратите внимание, что любой файл, который начинается со вставки дляданные, которых нет, работают просто отлично.

У кого-нибудь есть идеи, как решить эту проблему?

Редактировать: Вот код сверху вниз для ожидания готовности

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;
    }
}

А вот еще одна правка для образца файла.Я вырезал части данных для экономии места и включил только одну строку «sensor_temp_point» (в файле их 4).

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 ;

Ответы [ 3 ]

27 голосов
/ 22 марта 2011

readLine() вернет null, когда достигнет конца файла.Нет смысла ждать повторного чтения - вам нужно просто остановиться на этом.

РЕДАКТИРОВАТЬ: Хорошо, теперь код работает - вам действительно нужно реорганизовать это.Это в значительной степени не читается в данный момент.Разделите его на более мелкие методы и закройте программу чтения файлов в блоке finally, а не в огромном количестве мест, где вы в данный момент делаете это.

Не совсем понятно, что происходит,но обычно для циклического просмотра содержимого файла я бы использовал:

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

Когда readLine возвращает ноль, это означает, что данных больше нет.Я бы вообще не использовал ready().

Как только вы реорганизовали свой код ( просто , используя блок finally для закрытия файла, вы удалите около четверти метода - тогдарефакторинг это дальше) вам будет намного легче понять, что на самом деле происходит.

2 голосов
/ 22 марта 2011

Всякий раз, когда мне нужно прочитать файл, я выполняю поиск в Google по запросу «java read text file».(хорошая практика для многих задач, которые вы не хотите помнить, как это делать.) Есть много страниц, на которых показаны основные приемы чтения текстовых файлов.

Вот одна из них.http://www.javapractices.com/topic/TopicAction.do?Id=42

0 голосов
/ 29 марта 2011

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

Если я вас правильно понимаю, вы пытаетесь сказать, что вы хотите, чтобы ваш код читал текстовый файл одновременно с процессом (или потоком), который записывает в файл? Если это так, , что может быть вашей проблемой.

Когда программа выдает write() в файл, очень вероятно, что выходные данные будут где-то буферизованы. Буферизованные данные не будут записаны в настоящий файл, пока программа flush() -es из close() -es не выведет свой выходной файл. Поэтому вам может понадобиться взглянуть на другую программу, которая записывает данные, которые вы хотите прочитать.

Когда одна программа должна считывать данные одновременно с программой, которая записывает эти данные, две программы должны иметь некоторый контроль одновременности . В системах Unix (POSIX) программы, которые обмениваются данными таким образом, обычно используют канал, а не файл, а функциональность для обработки блокирующего ввода-вывода обеспечивает контроль параллелизма. Все сложнее, когда вы хотите использовать файл. Ваша программа чтения может пытаться опрашивать до тех пор, пока не прочитает отличительный шаблон, который указывает на конец текста. Вы можете использовать схему блокировки, чтобы файл блокировался до тех пор, пока писатель не завершил запись в файл.

...