Erro ao tentar filtrar matriz

2 respostas
P

Boa tarde, estou trabalhando com arquivos txt, ja consegui ler arquivos e tals. o problema é que eu leio um arquivo, trato esse arquivo e jogo em uma matriz, até ai tudo bem, segue o método que le esse arquivo:

#Código

public static String[][] leitorTestOrder(String path) throws IOException {
BufferedReader buffRead = new BufferedReader(new FileReader(path));
String linha = "";
String convertSpaceLine = "";
int ContadorTestOrder = 0;
String testOrder[][] = new String[30000][30]; //Guarda as informações do board
while (true) {
if (linha != null) {
System.out.println(linha + " , Linha sem espaço:" + convertSpaceLine);
} else {
break;
}
linha = buffRead.readLine();
// Pega a linha para remover os espaços em branco e deixar
// apenas um espaço.
convertSpaceLine = linha;
Character caracterEsepcial = '"';
if ((linha != null) && (!linha.contains("!"))) {
while ((convertSpaceLine.contains(" ")) || (convertSpaceLine.contains(caracterEsepcial.toString()))) {
convertSpaceLine = convertSpaceLine.replace(" ", " ");
convertSpaceLine = convertSpaceLine.replace(caracterEsepcial.toString(), "");
}
testOrder[ContadorTestOrder] = convertSpaceLine.split(" ");
ContadorTestOrder++;
}
}
buffRead.close();
return testOrder;
}

a partir deste ponto eu chamo a função acima no código fonte do meu GUI e armazeno o retorno em uma matriz do mesmo tipo e tamanho

#Código

String testOrder[][] = new String[30000][30]; //Guarda as informações do board
String componente[] = new String[1000]; //Guarda as informações do componente
//Armazena o caminho indicados pelo usuário:
pathTestOrder = txtCaminhoTestOrder.getText();
try {
//Armazena os dados do TestOrder no array board:
testOrder = ManipuladorArquivo.leitorTestOrder(pathTestOrder + "testorder");
JOptionPane.showMessageDialog(rootPane, testOrder, "Informação", JOptionPane.INFORMATION_MESSAGE);
lblMsg.setText("Lendo arquivo TestOrder e gerando parâmetros...");
} catch (IOException ex) {
Logger.getLogger(UI_BomCalculator.class.getName()).log(Level.SEVERE, null, ex);
}

até aqui tudo certo, ele le o arquivo, faz o tratamento e joga na matriz testOrder que vou usar adiante.
O que preciso dessa matriz são os indices de 0 a 4
Se na linha 1, coluna 0 contem o nome “test” && linha 1, coluna 3 nao tem o nome “version” ou é null eu vou abrir um arquivo em um determinado caminho.
Se na linha 1, coluna 0 contem o nome “test” && linha 1, coluna 3 contem o nome “version” ou é null eu vou abrir um arquivo em um outro caminho.
Acontece que só estou conseguindo filtrar pela linha 1 e coluna 0, segue o código:

#Código

if (testOrder[0][0].contentEquals("test"/*.contains("test".toLowerCase()*/)) { 
try {
componente = ManipuladorArquivo.leitorComponente(pathTestOrder + "\\\\analog\\\\" + testOrder[0][2]);
} catch (IOException ex) {
Logger.getLogger(UI_BomCalculator.class.getName()).log(Level.SEVERE, null, ex);
} 
}

Da forma acima funciona, mas quando vou filtrar tambem pela linha 1 e coluna 3 ocorre erro, a coluna 3 pode nao ter nada, pode ter a string “version” e pode ter outra string qualquer, mas para meu uso só me interessa se ela tiver vazia ou conter ou nao o a string “version” segue cógido:

#Código

if (testOrder[0][0].contentEquals("test"/*.contains("test".toLowerCase()*/)) {
if (testOrder[0][3].contentEquals(null)) {
try {
componente = ManipuladorArquivo.leitorComponente(pathTestOrder + "\\\\analog\\\\" + testOrder[0][2]);
} catch (IOException ex) {
Logger.getLogger(UI_BomCalculator.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

O erro é esse:

Exception in thread AWT-EventQueue-0 java.lang.ArrayIndexOutOfBoundsException: 3

at bomcalculator.UI_BomCalculator.btnGerarTestesActionPerformed(UI_BomCalculator.java:174)

at bomcalculator.UI_BomCalculator.access$000(UI_BomCalculator.java:10)

at bomcalculator.UI_BomCalculator$1.actionPerformed(UI_BomCalculator.java:57)

at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)

at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)

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:6533)

at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)

at java.awt.Component.processEvent(Component.java:6298)

at java.awt.Container.processEvent(Container.java:2236)

at java.awt.Component.dispatchEventImpl(Component.java:4889)

at java.awt.Container.dispatchEventImpl(Container.java:2294)

at java.awt.Component.dispatchEvent(Component.java:4711)

at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)

at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)

at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)

at java.awt.Container.dispatchEventImpl(Container.java:2280)

at java.awt.Window.dispatchEventImpl(Window.java:2746)

at java.awt.Component.dispatchEvent(Component.java:4711)

at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)

at java.awt.EventQueue.access$500(EventQueue.java:97)

at java.awt.EventQueue$3.run(EventQueue.java:709)

at java.awt.EventQueue$3.run(EventQueue.java:703)

at java.security.AccessController.doPrivileged(Native Method)

at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)

at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90)

at java.awt.EventQueue$4.run(EventQueue.java:731)

at java.awt.EventQueue$4.run(EventQueue.java:729)

at java.security.AccessController.doPrivileged(Native Method)

at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)

at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)

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)

Pelo que entendi esta falando que excedeu o array, mas nao esta excendo o array.

2 Respostas

A

Você está tentando acessar uma posição inexistente no array.

O filtro permite a passagem de linhas sem caracteres, exemplo uma quebra de linha, ajuste-o para:
if (linha != null && !linha.contains("!") && !linha.replaceAll(" ", "").isEmpty())

Se o erro persistir, provavelmente o problema esta na forma como os informações estão ordenadas/estruturadas no arquivo.txt usado para teste.

A matriz gerada não terá necessariamente trinta colunas em todas as posições, em algumas terá o tamanho de colunas que o split gerar nesta instrução:
testOrder[ContadorTestOrder] = convertSpaceLine.split(" ").

Quando você fez o splite e atribuiu ao array bidimensional, você assumiu que as linhas seguem uma configuração e espera atribuir exatamente trinta posições em seu array bidimensional.

Quando tentou acessar um endereço que não existe, deu o erro inesperado:

Causas prováveis do problema:

I -  está no filtro;

II - na gravação do arquivo.txt;

III - ou em ambos.

Se foi no arquivo, os dados tem sua estrutura corrompida para fins de leitura, sendo necessário a reestruturação da informação.

Se o arquivo tiver uma quebra de linha, o filtro deixa passar uma linha em branco e quando você fizer o split, vai gerar um array vazio, sendo necessário atualizar o filtro.

Para visualizar a configuração das linhas após o processamento veja esta implementação:

public static void main(String[] args) {
        JFileChooser jfc = new JFileChooser();
        jfc.showOpenDialog(jfc);
        leitorTestOrder(jfc.getSelectedFile().getAbsolutePath());

    }
    //Trabalhar com previsão para a exceção NullPointerException
    public static String[][] leitorTestOrder(String path) {
        try {
            Stream<String> linhas = Files.lines(Paths.get(path), StandardCharsets.UTF_8);
            ArrayList<String[]> filtro = new ArrayList<>(linhas
                    .filter(linha -> !linha.contains("!") && !linha.replaceAll(" ", "").isEmpty())
                    .map(linha -> linha.replaceAll("\"", "").split(" "))
                    .collect(Collectors.toList())
            );
            /*o ideal é não gerar uma matriz maior do que o necessário
            não adianta informar a quantidade de colunas, pois depende exclusivamente da estrutura do arquivo a ser lido*/
            String retorno[][] = new String[filtro.size()][];
            for (int i = 0; i < retorno.length; i++) {
                retorno[i] = filtro.get(i);
                System.out.println(Arrays.toString(retorno[i]));//linha pode ser removida
            }
            return retorno;
        } catch (IOException ex) {
            return null;
        }
    }

Use o debug na linha destas instrução ContadorTestOrder++, e procure pela variável testOrder, vai ver linhas que não tem trinta colunas, bem como os dados armazenados em cada linha após o split.

P

Cara muito obrigado,

Meu arquivo não conterá linhas sem caracteres, mas para garantir fiz o ajuste que me indicou.

“addller:

String retorno[][] = new String[filtro.size()][];

esse trecho acima resolve o problema que eu teria mais pra frente no laço que vou fazer, pois dessa forma minha matriz terá exatamente o tamanho de linhas do meu arquivo convertido.

Não sabia que essa barra dentro de uma String tinha essa função tbm. muito obrigado, assim posso tirar a variável que criei pra contornar esse problema.

Obrigado pelas dicas, agr consigo dar continuidade ao desenvolvimento. vlw

Criado 30 de junho de 2017
Ultima resposta 3 de jul. de 2017
Respostas 2
Participantes 2