Read specific bytes from RandomAccessFile using FileChannel : Java - java

I have a RandomAccessFile and its FileChannel. What I'm trying to do is read a specific section of the bytes from said file; however, while looking over the FileChannel read methods, I didn't see overloads that would help with what I'm trying to do, only methods which would read the entire content, or read content to a specific position in the buffer that the read method takes in. Is there a method that I'm missing that will help me accomplish my goal of reading a specific chunk of bytes, or will I need to read in the entire channel into the buffer and then parse out the section somehow?

You can go to a specific position in the file using FileChannel#position(long) and then read a buffer in the desired size.

Related

Access the same file for read and write random position

Start by saying that I have not great experience in Java and I've done a lot of research. I would please ask you a specific question.
Thank you
I need to open a file for reading and writing from which I read and write a 512-byte blocks.
The file is fixed length and the information to be written will overlap with other existing.
For example, I read the first 512 bytes of the file and if it contains certain values write a block 512 to position 2048.
I tried using FileInputStream and FileOutputStream but every time I open with FileOutputStream the contents of the file are deleted.
It can be done with Java?
Roberto
Use a FileChannel; it allows random access to any part of a file, in read, write or any combination of both.
Example:
final Path path = Paths.get("path/to/the/file");
final FileChannel channel = FileChannel.open(path, relevantOptions);
Optionally, after that, you can use the .map() method.

Getting a wrong FileChannel size

I'm trying to get the size of a file contained in assets.
I'm using a FileChannel because I need a FileChannel later.
The file myfile.txt contains 7 bytes.
Here is my code:
AssetManager amgr;
AssetFileDescriptor afd;
FileChannel fchIn;
FileInputStream fis;
amgr=context.getAssets();
afd=amgr.openFd("myfile.txt");
fis=afd.createInputStream();
fchIn=fis.getChannel();
Log.d("mytag", fchIn.size());
Log.d("mytag", fis.available());
And the output is:
7237492
7
Why is the size returned by the FileChannel.size() method wrong ?
Thanks for your help
FileInputStream.getChannel() documentation says it "Returns a read-only FileChannel that shares its position with this stream." You are assuming that the channel begins and ends exactly at the boundaries of your file, which is the only way its total size() would match what you expect, but the documentation does not make that guarantee.
Also note that FileInputStream.available() is not documented to mean the same thing as total size -- technically, it is the amount of data available to read without needing to load/buffer more from the source. Unless the entire source has already been read into memory, it may have almost nothing to do with the actual file size.
I expect that the underlying FileChannel has access to a large range of bytes for multiple files, like all of your assets combined (and hence the large size), and you'd need to reference the AssetFileDescriptor's getStartOffset() and getLength() methods to know the actual position of the associated file's bytes within the channel. My guess is that AssetFileDescriptor.createInputStream() is giving you an object that already knows the position and range and takes care of that for you. If you're going to use the raw channel, then honor the information in the file descriptor. Also note that, per the documentation, if you move the position of the FileInputStream (e.g. by reading bytes) then you also move the position of the channel at the same time, so be careful if you're trying to use both.

Java: Reading a file containing both text and binary data

I'm having a problem with a new file format I'm being asked to implement at work.
Basically, the file is a text file which contains a bunch of headers containing information about the data in UTC-8, and then the rest of the file is the numerical data in binary. I can write the data and read it back just fine, and I recently added the code to write the headers.
The problem is that I don't know how to read a file that contains both text and binary data. I want to be able to read in and deal with the header information (which is fairly extensive) and then be able to continue reading the binary data without having to re-iterate through the headers. Is this possible?
I am currently using a FileInputStream to read the binary data, but I don't know how to start it at the beginning of the data, rather than the beginning of the whole file. One of the FileInputStream's constructors takes a FileDescriptor as the argument and I think that's my answer, but I don't know how to get one from another file reading class. Am I approaching this correctly?
You can reposition a FileInputStream to any arbitrary point by getting its channel via getChannel() and calling position() on that channel.
The one caveat is that this position affects all consumers of the stream. It is not suitable if you have different threads (for example) reading from different parts of the same file. In that case, create a separate FileInputStream for each consumer.
Also, this technique only works for file streams, because the underlying file can be randomly accessed. There is no equivalent for sockets, or named pipes, or anything else that is actually a stream.

Java 6 File Input Output Stream (same file)

I searched and looked at multiple questions like this, but my question is really different than anything I found. I've looked at Java Docs.
How do I get the equivalent of this c file open:
stream1 = fopen (out_file, "r+b");
Once I've done a partial read from the file, the first write makes the next read return EOF no matter how many bytes were in the file.
Essentially I want a file I/O stream that doesn't do that. The whole purpose of what I'm trying to do is to replace the bytes in an existing file in the current file. I don't want to do it in a copy or make a copy before I do the Read->Write.
You can use a RandomAccessFile.
As Perception mentions, you can use a RandomAccessFile. Also, in some situations, a FileChannel may work better. I've used these to handle binary file data with great success.
EDIT: you can get a FileChannel from the RandomAccessFile object using getChannel.

Best Way to Write Bytes in the Middle of a File in Java

What is the best way to write bytes in the middle of a file using Java?
Reading and Writing in the middle of a file is as simple as using a RandomAccessFile in Java.
RandomAccessFile, despite its name, is more like an InputStream and OutputStream and less like a File. It allows you to read or seek through bytes in a file and then begin writing over whichever bytes you care to stop at.
Once you discover this class, it is very easy to use if you have a basic understanding of regular file i/o.
A small example:
public static void aMethod(){
RandomAccessFile f = new RandomAccessFile(new File("whereDidIPutTHatFile"), "rw");
long aPositionWhereIWantToGo = 99;
f.seek(aPositionWhereIWantToGo); // this basically reads n bytes in the file
f.write("Im in teh fil, writn bites".getBytes());
f.close();
}
Use RandomAccessFile
Tutorial
Javadocs
Open the file in write mode without truncating it, seek to the desired offset, and write the desired data. Just be careful about text/binary mode.
I think it’s best to create file chunks every time. And when the file is downloaded, connect them together. Now I'm working on it.

Categories

Resources