开发者

RandomAccessFile readInt

how to read numbers from a file???

when i use readInt method i get big number, and it not equals number from a file.

how to fix it???

Scanner is not good idea, becouse file contains more then 1000 millions numbers... it will takes very long time...

yes, text file.

file contains numbers devided space symbols. for example ( 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();
      }
   }

so, i attached report:


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

t0 < t1 < t2 &l开发者_运维技巧t; t3 < t4

How to change behavior of my program that get this: t0 ~ t1 ~ t2 ~ t3 ~ t4 ???


A possible reason for the large number may be due to byte ordering. Java uses Big Endian by default when reading from a channel. If the file you are reading from is Little Endian, then small numbers will become large, because the least significant byte becomes the most significant byte.

You can change the byte ordering of ByteBuffer by using the order method.


If you want to randomly access data, you need to be able to determine where to start and where to finish. With a text format this can be tricky and you may have to read all the previous lines/text to find the one you want.

With binary formats, you may be able to calculate exactly where you want to read, but you need to know how the number was encoded. e.g. was it big endian or little endian?

Scanner may not be optimal for text, and useless for binary data, but if may be more than fast enough.

Much of the time taken to scan a large file is the time it takes to read off disk (assuming it won't fit in memory) you can speed up this significantly if the file compresses well, e.g. text full of numbers does. Instead of taking 20 seconds to read it might take only 2 seconds if compressed. (And it might fit in the OS file cache)


This all depends on how the numbers are stored.

I guess the short answer is: One way or another, you have to know where the number starts and where it ends, and whether it is stored as text or in binary, and if it's in binary what the byte order is, i.e. little-endian or big-endian.

If it's stored as text, build a String from the digits, then call Integer.parseInt on that String. (Or if it's a floating point number, Double.parseDouble, etc for other data types.)

If it's stored as a binary integer, then read the bytes in to an array, or read them one by one, then multiply by powers of 256 and add together.

For example, suppose you have a four-byte number in little-endian order. You read it into a byte array of size 4. Then:

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;


If your numbers are stored as text readInt() won't work. You must parse the file, it is the only way.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜