Чтение данных из RandomAccessFile приводит к неверным результатам - Java

У меня есть текстовый файл с 42 строками. В каждой строке более 22 000 номеров, разделенных запятыми.

Я хотел извлечь определенные числа из каждой строки, и у меня есть массив int длиной 1000, содержащий 1000 чисел, которые мне нужны из каждой из этих 42 строк.

Например, если массив содержит 43, 1, 3244, это означает, что мне нужны 43-е число, 1-е число и 3244-е числа из каждой строки, начиная с первой строки, заканчивающейся 42-й строкой.

Мой цикл for, похоже, не работает, он читает только первую строку из текстового файла, который содержит 42 строки из 220000 чисел, и я не знаю, где он идет не так.

for(int i=0;i<42;i++){ //irretates through the 42 lines of 
    counter=1; // to keep track about on which line the code is working
    System.out.println("Starting line"+i);

    st2=new StringTokenizer(raf1.readLine(),",");
    //raf3 is a RandomAccessFile object containing the 42 lines

    a:while(st2.hasMoreTokens()){
        b=is_there(array2,counter);
        // is_there is a method that compares the rank of the taken being read with 
       //the whole array that has the 1000 numbers that i want. 
        if(b==false){ 
            // if the rank or order of token [e.g. 1st, 432th] we are stopping at 
           //is not among the 1000 numbers in the array 
            counter++;                  
            continue a;
        }
        else{ //if true
            s2=st2.nextToken();
            raf2.writeBytes(s2); //write that token on a new empty text file 
            raf2.writeBytes(","); // follow the number with a comma
            counter++;
        }
    } // end of for loop



public static boolean is_there(int[] x,int y){
    boolean b=false;
    for(int i=0;i<x.length;i++){
        if(x[i]==y) {b=true; break;}
    }
    return b;

person Tagwa Warrag    schedule 23.04.2015    source источник
comment
Не могли бы вы выложить вывод программы?   -  person Distjubo    schedule 25.04.2015
comment
О, и, кстати, вам не нужен счетчик, вот для чего я   -  person Distjubo    schedule 25.04.2015
comment
Почему вы используете RandomAccessFile, когда обрабатываете все последовательно? Я предполагаю, что вы можете прочитать все это как одну строку из-за различных соглашений о завершении строк, и тогда вы получите исключение NullPointerException при создании StringTokenizer.   -  person ivant    schedule 25.04.2015
comment
Вы, конечно, не должны встраивать в код количество строк. Вам нужно просто обработать файл до конца, о чем будет сигнализировать readLine(), возвращающий ноль.   -  person user207421    schedule 25.04.2015
comment
Довольно, пожалуйста: разместите хорошо отформатированный код, который можно компилировать, и примеры входов и выходов. Мне очень трудно понять вашу проблему.   -  person Fox    schedule 25.04.2015
comment
@Distjubo: вывод находится в текстовом файле, он слишком большой, он не может скопировать и вставить все, я могу загрузить текстовый файл только в том случае, если это было возможно. И да, вы совершенно правы, мне не нужен счетчик! не очень чистый код!   -  person Tagwa Warrag    schedule 26.04.2015
comment
@ivant Я просто больше знаком с RandomAccessFile ......... И дело в том, что входной файл на самом деле был файлом .csv, который я могу открыть с помощью excel. Когда я преобразовал его в текстовый файл и открыл его с помощью текстовой панели, каждая строка в старом листе Excel была на одной строке, а числа были разделены запятой.   -  person Tagwa Warrag    schedule 26.04.2015
comment
@Fox код скомпилирован ... вход и выход - это текстовые файлы, которые содержат огромные данные, которые не публикуются! входной текстовый файл состоит из 43 строк. Каждая строка содержит более 22 000 целых чисел, разделенных запятыми.   -  person Tagwa Warrag    schedule 26.04.2015
comment
@TagwaWarrag вы пытались скомпилировать код, который вы здесь вставили? Бьюсь об заклад, вы этого не сделали. счетчик не определен, как и raf2, raf3, код не соответствует закрывающей скобке и так далее, и так далее. И да, вы можете упростить свою задачу, возможно, до 3 строк по 10 целых чисел и 5 целых чисел в массиве, чтобы иметь возможность продемонстрировать, какими вы ожидаете входные и выходные данные. И нет, это не выходит за рамки публикации. Вы можете легко вписать это в код.   -  person Fox    schedule 26.04.2015
comment
@amyassin Чего вы ждете от этой награды?   -  person Radiodef    schedule 26.04.2015
comment
@Fox Я СОСТАВИЛ И ЗАПУСТИЛ КОД, И Я УЖЕ ЗАЯВИЛ, ЧТО ЭТО ДАЕТ НЕПРАВИЛЬНЫЙ РЕЗУЛЬТАТ. Здесь я вставил только цикл for и метод, который использовал для сравнения, а не весь код.   -  person Tagwa Warrag    schedule 26.04.2015
comment
@Radiodef ответ!   -  person amyassin    schedule 26.04.2015
comment
@amyassin Тогда я восстановил свой ответ. Это не получило никаких комментариев, и я не был уверен, что происходит, когда я заметил, что награда была назначена кем-то, кроме OP.   -  person Radiodef    schedule 26.04.2015
comment
Награда соответствует принятому ответу, решает ОП.   -  person amyassin    schedule 26.04.2015
comment
@TagwaWarrag, как вы себя заявляете. Это только часть компилируемого кода. И вы не пытались скомпилировать эту часть в одиночку. Я сделал пример из вашего кода, поэтому знаю, что это возможно. Вы бы ответили раньше и лучше, если бы последовали моему совету. Но тебе, кажется, все равно. Удачи. о, и кстати. кричит на меня за попытку помочь тебе ... :-D   -  person Fox    schedule 26.04.2015
comment
@Fox OP опубликовал код, хорошо отформатированный и с таким количеством объяснений и комментариев, которое казалось уместным .. Вы можете работать более гладко, добавив однозначное число повторений .. Не все люди раньше получали значок Mortarboard ;-)   -  person amyassin    schedule 26.04.2015
comment
@amyassin вежливо просит рабочий код и слишком сложно задать вопрос новичку? Во всяком случае, мы здесь оффтопы. Удачи, ребята. Публикация чего-то вроде this, вероятно, дала бы ответ в считанные минуты.   -  person Fox    schedule 26.04.2015
comment
@Fox Ну вот ... Хороший совет .. Спасибо :)   -  person amyassin    schedule 26.04.2015
comment
@Tagwa Warrag, почему бой все еще включен, если решение Radiodef работает?   -  person m.cekiera    schedule 28.04.2015


Ответы (2)


Ответ Radiodef правильный, но я думаю, что еще не хватает одного элемента. Код находит правильные числа, но печатает их в одной строке, потому что после цикла нет оператора 'next Line', который проходит через определенную строку (по крайней мере, не в приведенном выше коде), например, так:

        for(int i=0;i<42;i++){
        counter=1; // to keep track about on which TOKEN the code is working
        System.out.println("Starting line"+i);
        st2=new StringTokenizer(raf1.readLine(),",");
            while(st2.hasMoreTokens()){
                boolean b = is_there(array2,counter);
                if(!b){
                    st2.nextToken();
                }else{
                    String s2=st2.nextToken();
                    raf2.writeBytes(s2 + ",");
                }
                counter++;
            }
            raf2.writeBytes("\r\n");         //next line!
        }

Таким образом, он должен правильно читать, искать и печатать числа.

Более того, в комментариях есть ошибка: counter=1; // to keep track about on which line the code is working. counter отслеживает, на каком токене работает цикл, а не на строке.

КСТАТИ. метод is_there также может иметь более короткую форму:

public static boolean is_there(int[] x,int y){
    for(int i : x){
        if (i == y) return true;
    }
    return false;
}

Однако я не уверен, читабельнее ли это.

person m.cekiera    schedule 28.04.2015
comment
Спасибо вам точно! мой неправильный вывод был выстроен в одну строку вместо 43 строк. Еще раз спасибо. - person Tagwa Warrag; 30.04.2015
comment
@ m.cekiera Вы наверняка имели в виду if (i == y) return true; в is_there. - person Tobias Liefke; 30.04.2015
comment
@Radiodef вы приняли другого пользователя за автора сообщения. Тем не менее, я согласен с вами в этом вопросе - person m.cekiera; 03.05.2015
comment
@ m.cekiera Вы правы, это был сбой автозаполнения. Спасибо. - person Radiodef; 03.05.2015
comment
@TagwaWarrag Обратите внимание, что, хотя этот ответ является отличным предположением о вашем намерении, ваш вопрос абсолютно ничего не говорит о новых строках в выводе. Даже мой ответ был предположением, когда я его разместил. Из-за отсутствия подробностей на получение ответа на ваш вопрос требуется неделя и вознаграждение. См. stackoverflow.com/help/how-to-ask. - person Radiodef; 03.05.2015

Одна из ваших проблем заключается в том, что когда вы находите индекс, которого нет в вашем массиве, вы фактически не пропускаете токен:

if ( b == false ) {
    // don't actually skip the token !!
    counter++;                  
    continue a;
} else {
    s2 = st2.nextToken();
    raf2.writeBytes(s2);
    raf2.writeBytes(",");
    counter++;
}

Это означает, что ваш StringTokenizer получает 1 токен каждый раз, когда вы пытаетесь пропустить.

Это могло бы, например, привести к бесконечному циклу.

if ( b == false ) {
    // so skip the token !!
    st2.nextToken();

    counter++;                  
    continue a;
} else {
    s2 = st2.nextToken();
    raf2.writeBytes(s2);
    raf2.writeBytes(",");
    counter++;
}

В качестве примечания, цикл можно более элегантно переписать следующим образом:

while (st2.hasMoreTokens()) {
    s2 = st2.nextToken();

    if (is_there(array2, counter)) {
        raf2.writeBytes(s2);
        raf2.writeBytes(",");
    }

    ++counter;
}

Вам также следует:

person Radiodef    schedule 25.04.2015
comment
Спасибо, я не осознавал, что не пропускаю ненужные токены .... Я добавил вашу строку, но все еще не получил желаемого результата. Я думаю, что моя проблема связана с логикой, которую я использовал для поиска во входном текстовом файле и записи в выходной файл. - person Tagwa Warrag; 30.04.2015
comment
Я все еще не получаю желаемого результата Это не описание проблемы. - person Radiodef; 03.05.2015
comment
Цикл foor выбирает неправильные токены из каждой строки. - person Tagwa Warrag; 05.05.2015