улучшение извлечения данных из текстового файла в Java - PullRequest
3 голосов
/ 07 мая 2010

У меня есть файл CSV с образцами данных в этой форме:

220 30    255   0   0     Javascript
200 20      0 255 128     Thinking in java

, где первый столбец - высота, вторая толщина, следующие три - значения rgb для цвета, а последний - заголовок.Все должны рассматриваться как отдельные переменные.Я уже написал свое собственное решение для этого, но мне интересно, нет ли лучшего / более простого / более короткого пути сделать это.Извлеченные данные затем будут использованы для создания объекта Книги, разбрасывания каждой Книги в массив книг и распечатывания ее с размахом.Вот код:

private static Book[] addBook(Book b, Book[] bookTab){
        Book[] tmp = bookTab;
        bookTab = new Book[tmp.length+1];
        for(int i = 0; i < tmp.length; i++){
                bookTab[i] = tmp[i];
        }
        bookTab[tmp.length] = b;

        return bookTab;
}

public static void main(String[] args) {

    Book[] books = new Book[0];

    try {
        BufferedReader file = new BufferedReader(new FileReader("K:\\books.txt"));

        String s;
        while ((s = file.readLine()) != null) {
            int hei, thick, R, G, B;
            String tit;

            hei = Integer.parseInt(s.substring(0, 3).replaceAll(" ", ""));
            thick = Integer.parseInt(s.substring(4, 6).replaceAll(" ", ""));
            R = Integer.parseInt(s.substring(10, 13).replaceAll(" ", ""));
            G = Integer.parseInt(s.substring(14, 17).replaceAll(" ", ""));
            B = Integer.parseInt(s.substring(18, 21).replaceAll(" ", ""));

            tit = s.substring(26);

            System.out.println(tyt+wys+grb+R+G+B);

            books = addBook(new Book(wys, grb, R, G, B, tyt),books);
        }
        file.close();
    } catch (IOException e) {
        //do nothing
    }
}

Ответы [ 4 ]

1 голос
/ 07 мая 2010

У меня есть файл CSV с образцами данных в этой форме

Это не файл CSV . Это файл с фиксированной шириной.

Мне интересно, нет ли лучшего / более простого / короткого способа сделать это

Используйте настоящий формат файла CSV. Тогда разбирать / форматировать было бы легко с большим количеством доступных API Java CSV. Например OpenCSV . Вы даже можете использовать его для преобразования между List бобами (например, как Book в вашем случае) и CSV-файлом.

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

Regex только усугубит ситуацию, поскольку он не в обычном формате, а в фиксированном формате! Если вы не можете изменить формат, даже не CSV, тогда ваш подход будет таким же хорошим. Я бы только заменил replaceAll(" ", "") на trim(), так как это эффективнее (один - регулярное выражение, другой - просто разбор). Замена Book[] на List<Book> также является хорошим предложением, проще добавить еще одну книгу. Вы можете просто сделать books.add(book). Также см. Учебник Коллекции .

0 голосов
/ 07 мая 2010

Вам следует рассмотреть возможность использования java.util.Scanner класса , который был добавлен в Java 5. Он был специально создан для обработки подобных ситуаций разбора файлов и строк.

Воткраткий пример, основанный на формате вашего файла (ПРИМЕЧАНИЕ: я упускаю всю связанную с этим обработку ошибок для ясности / краткости):

import java.util.Scanner;
import java.io.File;
import java.lang.String;

class Dummy
{
    public static void main(String[] args) throws Exception
    {
       Scanner sc = new Scanner(new File("file.txt"));
       while(sc.hasNext())
       {
               int hei = sc.nextInt();
               int thick = sc.nextInt();
               int r = sc.nextInt();
               int g = sc.nextInt();
               int b = sc.nextInt();
               String title = sc.nextLine().trim();

               System.out.println("Book(" + hei + "," + thick + "," + 
               r + "," + g + "," + b + "," + title + ")");
       }
    }
}

Приятная вещь в Scanner состоит в том, что он имеет конструкторы, которые можно принимать в строках, Файлы или другие InputSources, так что вы можете использовать его практически с чем угодно.Надеюсь, это поможет!

0 голосов
/ 07 мая 2010

StreamTokenizer, кажется, сделано для этого, как предложено в этом примере .Это немного устарело, но может быть довольно быстро при использовании с BufferedReader.

0 голосов
/ 07 мая 2010

Вы не должны использовать подстроку, так как это ограничивает формат / длину ваших данных.Если у вас есть некоторый контроль над тем, как генерируется CSV (в частности, разделитель), вы можете использовать StringTokenizer.Вы также можете использовать массив для представления данных в одной строке (определив несколько констант, чтобы уточнить, какой элемент представляет, что).

...