views:

203

answers:

3

How to obtain a position in file (byte-position) from the java scanner?

Scanner scanner = new Scanner(new File("file"));
scanner.useDelimiter("abc");
scanner.hasNext();
String result = scanner.next();

and now: how to get the position of result in file (in bytes)?

Using scanner.match().start() is not the answer, because it gives the position within internal buffer.

+2  A: 

Scanner provides an abstraction over the underlying Readable, whose content need not necessarily come from a File. It doesn't directly support the kind of low-level query that you're looking for.

You may be able to compute this number by combining the internal buffer position according to the Scanner and the number of bytes read according to the Readable, but even this looks to be a tricky proposition. If an approximate location within a huge file is acceptable, then this may be good enough.

polygenelubricants
+1  A: 

Its possibe using RandomAccessFile.. try this..

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

public class RandomFileAccessExample 
{
    RandomFileAccessExample() throws IOException
    {
        RandomAccessFile file = new RandomAccessFile("someTxtFile.txt", "r");
        System.out.println(file.getFilePointer());
        file.readLine();
        System.out.println(file.getFilePointer());
    }
    public static void main(String[] args) throws IOException {
        new RandomFileAccessExample();
    }

}
echo
Ok, but with RandomAccessFile I can't use Regular Expressions in such a easy way as with Scanner...
september2010
thats right! but one way of doing is read all the lines, store it in a string and use regEx in the string.. I know! this sounds very bad! :)
echo
it's impossible -- my files are to big to read it at once
september2010
java as such do not provide tokenizer with RandomAccessFile. What else can we do!? build up some logic. read line by line and tokenize it.!
echo
A: 

You can get an approximate file position by using a custom FileInputStream to create the Scanner, like this:

final int [] aiPos = new int [1];
FileInputStream fileinputstream = new FileInputStream( file ) {
   @Override
   public int read() throws IOException {
       aiPos[0]++;
       return super.read();
   }
   @Override
   public int read( byte [] b ) throws IOException {
       int iN = super.read( b );
       aiPos[0] += iN;
       return iN;
   }
   @Override
   public int read( byte [] b, int off, int len ) throws IOException {
       int iN = super.read( b, off, len );
       aiPos[0] += iN;
       return iN;
   }
};

Scanner scanner = new Scanner( fileinputstream );

This will give you a position accurate to within 8K or so, depending on the implementation of FileInputStream. This is useful for things like updating progress bars during a file parse, where you don't need the exact position, just something reasonably close.

Wade Walker