RandomAccessFile readInt - PullRequest
       10

RandomAccessFile readInt

0 голосов
/ 02 декабря 2010

как читать числа из файла ???

когда я использую метод readInt, я получаю большое число, а оно не равно числу из файла.

как это исправить ???

Сканер не очень хорошая идея, потому что файл содержит более 1000 миллионов номеров ... это займет очень много времени ...

да, текстовый файл.

Файл содержит числа разделенных пробелами символов.например (test.txt)

1 2 4 -4004 15458 8876


   public static void readByMemoryMappedFile(int buffer[], String filename) throws IOException
   {
      int count = 0;

      RandomAccessFile raf = new RandomAccessFile(filename, "r");
      try {
            MappedByteBuffer mapFile = raf.getChannel().map(MapMode.READ_ONLY, 0, raf.length());

            StringBuilder b = new StringBuilder();
            try {
                  while (mapFile.hasRemaining()) {
                        byte read = mapFile.get();
                        if (read == ' ' && b.length() > 0) {
                              buffer[count++] = mapFile.getInt();//Integer.parseInt(b.toString());
                              b.delete(0, b.length());
                        } else {
                              b.append((char) read);
                        }
                  }
            } catch (BufferUnderflowException e) {
                  // Всё, файл закончился
            }
            if (b.length() > 0) {
                  buffer[count++] = Integer.parseInt(b.toString());
            }
      } finally {
            raf.close();
      }
   }

Итак, я приложил отчет:


// operation: time
reading: 39719   // t0
reading: 28297   // t1
reading: 56719   // t2
reading: 125735  // t3
reading: 199000  // t4

t0

Как изменить поведение моей программы, которая получает это: t0 ~ t1 ~ t2 ~ t3 ~ t4 ???

Ответы [ 4 ]

2 голосов
/ 02 декабря 2010

Возможная причина большого числа может быть из-за порядка байтов.Java использует Big Endian по умолчанию при чтении из канала.Если файл, из которого вы читаете, является Little Endian, то маленькие числа станут большими, потому что младший байт становится самым старшим байтом.

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

1 голос
/ 02 декабря 2010

Все зависит от того, как хранятся числа.

Полагаю, короткий ответ таков: так или иначе, вы должны знать, где начинается число и где оно заканчивается, и хранится ли оно кактекст или в двоичном формате, и если он в двоичном виде, то есть порядок байтов, то есть с прямым порядком байтов или с прямым порядком байтов.

Если он хранится как текст, создайте строку из цифр, а затем вызовите Integer.parseIntэта строка(Или, если это число с плавающей запятой, Double.parseDouble и т. Д. Для других типов данных.)

Если оно хранится как двоичное целое число, то считывает байты в массив или считывает их один за другим,затем умножьте на степени 256 и сложите вместе.

Например, предположим, что у вас есть четырехбайтовое число в порядке с прямым порядком байтов.Вы читаете его в байтовый массив размером 4. Тогда:

byte[] incoming=new byte[4];
file.read(incoming);
int n=0;
for (int p=0;p<4;++p)
  n=n*256+incoming[p];
return n;
1 голос
/ 02 декабря 2010

Если вы хотите получить произвольный доступ к данным, вам необходимо определить, с чего начать и где закончить. С текстовым форматом это может быть сложно, и вам, возможно, придется прочитать все предыдущие строки / текст, чтобы найти ту, которая вам нужна.

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

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

Большая часть времени, необходимого для сканирования большого файла, - это время, которое требуется для считывания с диска (при условии, что он не помещается в памяти), вы можете значительно ускорить это, если файл хорошо сжимается, например текст, полный цифр делает. Вместо 20 секунд на чтение может потребоваться всего 2 секунды, если они сжаты. (И это может поместиться в файловом кеше ОС)

0 голосов
/ 02 декабря 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...