0

すべての種類のファイル (Microsoft メモ帳など) を読み込もうとしています。私が持っている SwingWorker は通常のテキストを問題なくロードできますが、mp3、pdf などのファイルをロードしようとすると、NullPointerException が発生します。

誰かが私のコードを見て、mp3、pdf などのファイルでこのエラーが発生し続ける理由を理解できますか? 私が言ったように、エラーなしで通常の.htmlプレーンテキストファイルをロードできます。

class Open extends SwingWorker<StringBuilder, Void>
{
    File file;
    JTextArea jta;

    Open(File file, JTextArea jta)
    {
        this.file = file;
        this.jta = jta;
    }

    @Override
    protected StringBuilder doInBackground() throws Exception
    {
        BufferedReader br = null;
        StringBuilder b = new StringBuilder();

        try
        {
            br = new BufferedReader(new FileReader(file));

            while(br.ready())
            {
                b.append(br.readLine() + "\n");
            }
        }
        finally
        {
            try
            {
                br.close();
            } catch (IOException e) { }
        }
        return b;
    }

    @Override
    protected void done()
    {
        try {
            jta.append(get().toString());
        } catch (InterruptedException ex) {
            Logger.getLogger(Open.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ExecutionException ex) {
            Logger.getLogger(Open.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

これは、コードを次のように変更した後に得られるものです。

class Open extends SwingWorker<Void, String>
{
    File file;
    JTextArea jta;

    Open(File file, JTextArea jta)
    {
        this.file = file;
        this.jta = jta;
    }

    @Override
    protected Void doInBackground() throws Exception
    {
        BufferedReader br = null;

        try
        {
            br = new BufferedReader(new FileReader(file));

            String line = br.readLine();

            while(line != null)
            {
                publish(line);
                line = br.readLine();
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            try
            {
                br.close();
            } catch (IOException e) { }
        }
        return null;
    }

    @Override
    protected void process(List<String> chunks)
    {
        for(String s : chunks)
            jta.append(s + "\n");
    }
}

これは、Netbeans の「スタック トレース」(だと思います) です。

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
        at java.util.Hashtable.put(Hashtable.java:394)
        at sun.font.PhysicalStrike.getGlyphPoint(PhysicalStrike.java:112)
        at sun.font.SunLayoutEngine.nativeLayout(Native Method)
        at sun.font.SunLayoutEngine.layout(SunLayoutEngine.java:133)
        at sun.font.GlyphLayout$EngineRecord.layout(GlyphLayout.java:648)
        at sun.font.GlyphLayout.layout(GlyphLayout.java:447)
        at sun.font.ExtendedTextSourceLabel.createGV(ExtendedTextSourceLabel.java:308)
        at sun.font.ExtendedTextSourceLabel.getGV(ExtendedTextSourceLabel.java:294)
        at sun.font.ExtendedTextSourceLabel.createCharinfo(ExtendedTextSourceLabel.java:563)
        at sun.font.ExtendedTextSourceLabel.getCharinfo(ExtendedTextSourceLabel.java:492)
        at sun.font.ExtendedTextSourceLabel.getLineBreakIndex(ExtendedTextSourceLabel.java:438)
        at java.awt.font.TextMeasurer.calcLineBreak(TextMeasurer.java:308)
        at java.awt.font.TextMeasurer.getLineBreakIndex(TextMeasurer.java:544)
        at java.awt.font.LineBreakMeasurer.nextOffset(LineBreakMeasurer.java:340)
        at java.awt.font.LineBreakMeasurer.nextLayout(LineBreakMeasurer.java:422)
        at javax.swing.text.TextLayoutStrategy.sync(TextLayoutStrategy.java:298)
        at javax.swing.text.TextLayoutStrategy.insertUpdate(TextLayoutStrategy.java:52)
        at javax.swing.text.FlowView.loadChildren(FlowView.java:126)
        at javax.swing.text.CompositeView.setParent(CompositeView.java:122)
        at javax.swing.text.FlowView.setParent(FlowView.java:272)
        at javax.swing.plaf.basic.BasicTextAreaUI$PlainParagraph.setParent(BasicTextAreaUI.java:222)
        at javax.swing.text.CompositeView.replace(CompositeView.java:200)
        at javax.swing.text.BoxView.replace(BoxView.java:164)
        at javax.swing.text.View.updateChildren(View.java:1095)
        at javax.swing.text.View.insertUpdate(View.java:679)
        at javax.swing.plaf.basic.BasicTextUI$RootView.insertUpdate(BasicTextUI.java:1590)
        at javax.swing.plaf.basic.BasicTextUI$UpdateHandler.insertUpdate(BasicTextUI.java:1849)
        at javax.swing.text.AbstractDocument.fireInsertUpdate(AbstractDocument.java:185)
        at javax.swing.text.AbstractDocument.handleInsertString(AbstractDocument.java:734)
        at javax.swing.text.AbstractDocument.insertString(AbstractDocument.java:693)
        at javax.swing.text.PlainDocument.insertString(PlainDocument.java:114)
        at javax.swing.JTextArea.append(JTextArea.java:470)
        at Open.process(main.java:313)
        at javax.swing.SwingWorker$3.run(SwingWorker.java:391)
        at sun.swing.AccumulativeRunnable.run(AccumulativeRunnable.java:95)
        at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.run(SwingWorker.java:860)
        at sun.swing.AccumulativeRunnable.run(AccumulativeRunnable.java:95)
        at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.actionPerformed(SwingWorker.java:870)
        at javax.swing.Timer.fireActionPerformed(Timer.java:271)
        at javax.swing.Timer$DoPostEvent.run(Timer.java:201)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

コードを次のように変更しました。

class Open extends SwingWorker<Void, String>
{
    File file;
    JTextArea jta;

    Open(File file, JTextArea jta)
    {
        this.file = file;
        this.jta = jta;
    }

    @Override
    protected Void doInBackground() throws Exception
    {
        BufferedReader br = null;

        try
        {
            br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));

            String line = br.readLine();

            while(line != null)
            {
                publish(line);
                line = br.readLine();
            }
        }
        catch (Exception e) { e.printStackTrace(); }
        finally
        {
            try
            {
                if(br != null)
                    br.close();
            } catch (IOException e) { }
        }
        return null;
    }

    @Override
    protected void process(List<String> chunks)
    {
        for(String s : chunks)
            jta.append(s + "\n");
    }
}

そして、私はまだNPEを受けています。

4

4 に答える 4

1

ファイルのオープンに失敗した場合brでもnull、 は呼び出し先の finally ブロックにありますbr.close()。したがって、NPE を取得します。

FileReaderを使用してpng、pdf、またはその他のファイルを読み取ろうとすることは無意味であることを追加する必要があります。ファイルを開くことに成功したとしても、Reader を使用して読み取ると、バイトから文字に変換するときに (バイナリ) コンテンツが破損する可能性があります。BufferedReader.readLine() 呼び出しは事態を悪化させるだけです...

編集 - 提供されたスタックトレースは、問題が投稿したコードに関連していないことを明確に示しています。しかし、私の主張はまだ立っています。あなたが投稿したコードは、私が説明した状況で NPEをスローします。

スタックトレースは、「PlainDocument」がテキストとして偽装したランダムながらくたをレンダリングできないと言っているようです。(おそらくガベージ) 文字のグリフ情報を作成しようとしているように見えますが、一部のデータ構造が作成/提供されていないために失敗しています。これを理解するには、Sun のソース コードを調べ始める必要があると思います。適切な IDE も役立つでしょう。

編集 2 - 私の知る限り、Swing JTextArea のコンテキストでバイナリ ファイルを処理する方法は 2 つあります。

  1. ファイルをバイトとして (ストリームを使用して) 読み取り、バイトを表示可能なものに変換し (たとえば、表示できない文字を表示可能な文字のシーケンスに置き換える)、読み取り専用の PlainDocument を使用してそれらを表示することができます。

  2. バイナリ ファイルを編集できるものが必要な場合 (それが賢明なアイデアかどうかはわかりません)、独自の Document タイプを作成する必要があると思います。それは大きな仕事かもしれません。

于 2009-12-20T03:56:13.123 に答える
1

Java のドキュメントでは、テキスト以外のファイルにはFileReaderを使用しないでください。代わりに FileInputStream を使用してください。

元のコードでそのルートを試すかもしれません...

于 2009-12-20T04:00:58.257 に答える
0

brを作成するためにこれを試してください

br = new BufferedReader(new InputStreamReader(new FileInputStream(file), Charset.forName("US-ASCII")));

それが機能する場合も試してください

br = new BufferedReader(new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")));

それが機能するかどうかを確認します (java.nio.charset.Charset をインポートする必要があります)。

于 2009-12-20T05:03:43.430 に答える
0

あなたのエラーは関数 Open.process() です

スタックトレースの重要な部分は次のとおりです。

at javax.swing.JTextArea.append(JTextArea.java:470)
at Open.process(main.java:313)

ほとんどの場合、問題は null 文字列を追加していることです。挿入するテキストが null でないことを確認してください。

これを試して:

    for(String s : chunks)
        if(s != null)
            jta.append(s + "\n");

もう 1 つは、これらの例外を無視しないように注意してください。

try{ ... } catch(Exception e){ }

例外が問題にならないことが確実にわかっている場合を除きます (スレッドで何かを待機しているときに中断された例外など)。e.printStackTrace(); を呼び出す必要があります。少なくとも、予期しない問題が発生したことを少なくとも確認できるようにするためです。

あなたが投稿したコードでは、最初は読み取り時、次に終了時の2つのエラーを無視しました。

于 2009-12-20T04:07:04.953 に答える