NullPointerException при записи в RandomAccessFile

Я могу писать в файл произвольного доступа сразу после его создания, но как только я пытаюсь писать из своей функции, он ломается.

private void openFile()
{
    JFileChooser fileChooser = new JFileChooser();

    fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY );
    int result = fileChooser.showSaveDialog( this );

    // user clicked Cancel button on dialog
    if ( result == JFileChooser.CANCEL_OPTION )
    {
        return;
    }

    File fileName = fileChooser.getSelectedFile();

    if ( fileName == null || fileName.getName().equals( "" ) )
    {
    JOptionPane.showMessageDialog( this,
        "Invalid File Name",
        "Invalid File Name",
        JOptionPane.ERROR_MESSAGE );
    }
    else 
    {
     // Open the file
        try 
        {
            RandomAccessFile output = new RandomAccessFile( fileName, "rw" );
            createRecord();
        }
        catch ( IOException e ) 
        {
            JOptionPane.showMessageDialog( this,
            "File does not exist",
            "Invalid File Name",
            JOptionPane.ERROR_MESSAGE );
        }      
    }
}

private void createRecord()
{
    String firstName = tfdFirst.getText();
    String lastName = tfdLast.getText();
    String emailAddress = tfdEmail.getText();
    String homeAddress = tfdAddress.getText();
    Long phoneNumber = new Long(tfdPhone.getText());
    char gender = tfdGender.getText().charAt(0);

    System.out.println(firstName + lastName + emailAddress + homeAddress + phoneNumber + gender);

    try
    {
        output.seek(0);
        output.writeChar(gender);
        writeString( output, lastName);
        writeString( output, firstName);
        writeString( output, emailAddress);
        writeString( output, homeAddress);
        output.writeLong(phoneNumber);
    }
    catch(IOException ex)
    {
        ex.printStackTrace();
    }
}

Извините за стену кода, но это две оскорбительные функции. Первый пытается открыть RandomAccessFile с именем output перед вызовом createRecord(), который пытается записать пользовательский ввод из JFrame в файл. Если я поставлю простую функцию writeInt() вместо createRecord(), то она будет работать нормально, но как только будет вызвана createRecord(), вывода как будто никогда не существовало.

Я работал над этим часами безрезультатно, поэтому, если кто-то может помочь найти решение, я был бы очень благодарен.

Изменить: трассировка стека по запросу. (Осторожно, очень долго...)

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at good_gals_customer_app.NewCustomerUI.createRecord(NewCustomerUI.java:298)
at good_gals_customer_app.NewCustomerUI.openFile(NewCustomerUI.java:273)
at good_gals_customer_app.NewCustomerUI.butCreateRecordActionPerformed(NewCustomerUI.java:186)
at good_gals_customer_app.NewCustomerUI.access$100(NewCustomerUI.java:21)
at good_gals_customer_app.NewCustomerUI$2.actionPerformed(NewCustomerUI.java:87)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2346)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6527)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6292)
at java.awt.Container.processEvent(Container.java:2234)
at java.awt.Component.dispatchEventImpl(Component.java:4883)
at java.awt.Container.dispatchEventImpl(Container.java:2292)
at java.awt.Component.dispatchEvent(Component.java:4705)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4533)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462)
at java.awt.Container.dispatchEventImpl(Container.java:2278)
at java.awt.Window.dispatchEventImpl(Window.java:2739)
at java.awt.Component.dispatchEvent(Component.java:4705)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:746)
at java.awt.EventQueue.access$400(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:697)
at java.awt.EventQueue$3.run(EventQueue.java:691)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue$4.run(EventQueue.java:719)
at java.awt.EventQueue$4.run(EventQueue.java:717)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:716)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

person Clabbage    schedule 08.11.2014    source источник
comment
Трассировка стека, пожалуйста, также укажите строку, которая вызывает NPE   -  person MadProgrammer    schedule 08.11.2014
comment
Я даже не вижу, как этот код компилируется; output не объявлен в createRecord()   -  person fge    schedule 08.11.2014
comment
@fge И есть проблема, output, вероятно, является полем экземпляра   -  person MadProgrammer    schedule 08.11.2014
comment
О, извините, вывод объявлен в классе, который содержит эти функции. Строки, вызывающие NPE, — это то место, где я пытаюсь записать файл в createRecord.   -  person Clabbage    schedule 08.11.2014


Ответы (1)


У вас, похоже, проблема с теневым копированием...

Вы создали локальную переменную output в openFile...

RandomAccessFile output = new RandomAccessFile( fileName, "rw" );

Но есть доступ, который выглядит как переменная экземпляра в createRecord...

output.seek(0);

По всей вероятности, переменная экземпляра null...

Обычно я бы предложил удалить повторное объявление и использовать поле экземпляра, но в этом, я думаю, вам следует избавиться от поля экземпляра и передать ссылку RandomAccessFile методу createRecord

Вы также не управляете своими ресурсами, помните, если вы открываете, вы должны закрыть его...

try (RandomAccessFile output = new RandomAccessFile( fileName, "rw" ))
{
    createRecord(output);
}
catch ( IOException e ) 
{
    JOptionPane.showMessageDialog( this,
    "File does not exist",
    "Invalid File Name",
    JOptionPane.ERROR_MESSAGE );
}      

Дополнительные сведения см. в Утверждении о попытке использования ресурсов. Детали

person MadProgrammer    schedule 08.11.2014
comment
Благодарю вас! Теперь это работает. Кроме того, я планировал добавить закрывающий код позже, я хотел сначала убедиться, что смогу писать. - person Clabbage; 08.11.2014
comment
Не закрытие файла может привести к тому, что файл не будет сброшен, если вы знаете;) - person MadProgrammer; 08.11.2014