How to implement seek() function in BufferSink (or BufferedSource) in OKHttp?
We all know that in Java, the RandomAccessFile class has a method seek(long), which enable us to start reading/writing a file from a specific position, and the bytes before the postion will be discarded. Is there any similar methods in OKHttp?
I have noticed that there is a method in BufferedSink:
write(byteString: ByteString, offset: Int, byteCount: Int)
But unfortunately the parameter "offset" aceepts only type int, not type long, which has some limit when transmitting large files.
The API you're looking for is BufferedSource.skip().
In Okio 3.0 (coming soon) we’re adding a new Cursor class that'll make skip() faster if the underlying source is a File.
https://github.com/square/okio/issues/889
I am using Okio.buffer to read an image file from the assets folder like this:
BufferedSource img = Okio.buffer(Okio.source(getAssets().open("image.jpg")));
byte[] image = img.readByteArray();
Related
I am using netcdf-java to access netcdf files and variables. I wonder how I can get each variable's start offset and seek to that offset directly. The following is my current code which I get the variables from the method findVariable
NcHdfsRaf raf = new NcHdfsRaf(file, job.getConfiguration());
NetcdfFile ncfile = WRFFile.openFile(raf, path.toString());
Variable timesVar = ncfile.findVariable("Temperature");
Huh. Why do you want that? It's probably a terrible idea. You already have an interface for reading data, and that interface insulates you from any underlying file format changes. Furthermore, remember that netcdf is a portable file format: if you read 1000 bytes from a given offset, those bytes might not be what you expect -- the library will deal with endian conversions and any possible type conversions that must happen.
With all that out of the way, if for some goofy reason you wanted to get the offset, I don't see anything in the Java class that will let you do that:
http://www.unidata.ucar.edu/software/thredds/current/netcdf-java/javadoc/ucar/nc2/Variable.html
If you were doing this in the C library, underneath the public API, you could peek at types of NC_Var: the 'begin' member of the struct is where data begins:
https://github.com/Unidata/netcdf-c/blob/master/include/nc3internal.h#L159
In Java, how would I convert a byte array (TCP packet payload from a pcap file) into some kind of HTTP object that I can use to get HTTP headers and content body?
One of the stupid lovely things about Java is a total lack of unsigned types. So, a good place to start would be taking your byte array and converting it into a short array to make sure that you don't have any rollover problems. (16 bits versus 8 bits per number).
From there, you could use a BufferedOutputStream to write your data to a file and parse it with one of the Java built-in XML readers, such as JaxB or DOM. BufferedOutputStream writes hex directly to a file, and can take an input of an int, byte, or short array. After you write it out, using the OutputStream it should be very simple to parse the HTML out of it.
If you need any help with any of these individual steps, I'd be happy to help.
EDIT: as maerics has pointed out, perhaps I didn't grasp what you were asking. Regardless, writing your byte array with a BufferedOutputStream is the way to go in my opinion, and I could still help you build a parser if you want.
JNetPcap can do exactly this.
Here are examples for
Opening a pcap file
Parsing http (in the example, we extract an image)
Drawback: parsing http in this library is depracated*, but that doesn't mean it doesn't work
*I can't post anymore links without more reputation. Sorry. You can Google for "jnetpcap http deprecated"
Edit: I really just need to know when a Deflater derived class decides to write header and footer data, and how to exploit those facts. I would really like to do the following:
Prime the dictionary for a Deflater derived class with some bytes (I think I got this).
Send some data to be compressed to the Deflater derived class (I think I got this).
Output all of that compressed data (WITH NO HEADER OR FOOTER DATA) to wherever I want (Not sure how to do this, it would also be okay to have both header/footer, or just one, just as long as it was consistent).
Reuse object by starting again at 1.
Original Q: I am using the Java DeflaterOutputStream to compress some data. I am also modifying this compressed data by modifying the headers and the footers. I would like to give some input to DeflaterOutputStream, and have it only output the compressed data part, not the header or footer of the gzip format. How might I do this?
So far, I have been trying to do something like this:
internalWriter.write(storage, 0, amountRead);
internalWriter.finish();
internalWriter.getDef().reset();
internalWriter here is an extension of DeflaterOutputStream. This outputs the compressed data with header and footer. However, on subsequent calls with the same object, it outputs compressed data and footer. I basically want only the compressed data, or perhaps the same thing to happen each time. Any ideas? A quick explanation of how compression streams use close,flush,finish, might help me out too, with a focus on when the header and footer are created and outputted.
And every time I use DeflaterOutputStream, I want it to output everything right away. That is why I did the finish right after the right as seen above...
You can see good examples in Java Almanac
Compressing a Byte Array
Decompressing a Byte Array
--- EDIT ---
Let me try to help a little more. The book Java I/O by Elliote Rusty Harold is perhaps the best reference I have found. You can get it from OReilly Books. I will provide you with some quotes and examples from the book.
Deflating Data
The Deflater class contains methods to compress blocks of data. You
can choose the compression format, the level of compression, and the
compression strategy. Deflating data with the Deflater class requires
nine steps:
Construct a Deflater object.
Choose the strategy (optional).
Set the compression level (optional).
Preset the dictionary (optional).
Set the input.
Deflate the data repeatedly until needsInput( ) returns true.
If more input is available, go back to step 5 to provide additional input data. Otherwise, go to step 8.
Finish the data.
If there are more streams to be deflated, reset the deflater.
More often than not, you don’t use this class directly. Instead, you
use a Deflater object indirectly through one of the compressing stream
classes like DeflaterInputStream or DeflaterOutputStream. These
classes provide more convenient programmer interfaces for
stream-oriented compression than the raw Deflater methods.
Inflating Data
Construct an Inflater object.
Set the input with the compressed data to be inflated.
Call needsDictionary( ) to determine if a preset dictionary is required.
If needsDictionary( ) returns true, call getAdler( ) to get the Adler-32 checksum of the dictionary. Then invoke setDictionary( ) to
set the dictionary data.
Inflate the data repeatedly until inflate( ) returns 0.
If needsInput( ) returns true, go back to step 2 to provide additional input data.
The finished( ) method returns true.
Now, the book dedicates a whole chapter to compressing and decompressing data, and I do not think it possible to explain it all here. You'll have to do you part of task and if needed, come back with a narrower question.
See the deflater (sic) documentation. If nowrap is true, then there is no header or trailer generated -- just raw compressed data in the deflate format.
It sounds like you want to have two streams, your destination stream and then your compressor stream that decorates the destination stream. Then you'll write your uncompressed data to the base stream and the compressed data to the decorator stream. Make sure that you flush before switching. Reading will be a similar procedure, but you'll need to know where the compressed data begins and ends in your stream.
Suppose the destination stream is a file, something like the following pseudo code...
FileOutputStream dest = new FileOutputStream(foo);
DeflaterOutputStream decorator = new DeflaterOutputStream(dest);
byte[] header = getHeader();
byte[] body = getBody();
byte[] footer = getFooter();
dest.write(header);
dest.flush();
decorator.write(body);
decorator.flush();
dest.write(footer);
I wonder if DeflaterOutputStream is really what you want though. Isn't that part of a zip file? If you're doing something custom, it seems like you'd just want to gzip it.
Is it possible to attach file to JSONObject in Java (and to JSON at all)?
For example, can I attach bitmap to 'image' field?
{'user_id':'5', 'auth_token':'abc', 'image': ???}
You can convert the bitmap (or any binary data) to text using base64 (which makes it a String) I wouldn't use one of the Base64 classes in the JVM unless you are fully aware that they are for internal use. (may not be available on all JDKs and could change in future versions)
You could copy java.util.prefs.Base64 if you don't have one in a library already.
refer the answer of BalusC
A bitmap is binary data. JSON is to be represented as character data. So you need to convert binary data to character data and vice versa without loss of information.
Yes you can send image by converting that image into characters data,
I was creating a opengl android application. I was trying to render a opengl object with vertices more than 50,000.
float itemVerts [] = {
// f 231/242/231 132/142/132 131/141/131
0.172233487787643f, -0.0717437751698985f, 0.228589675538813f,
0.176742968653347f, -0.0680393472738536f, 0.2284149434494f,
0.167979223684599f, -0.0670168837233226f, 0.24286384937854f,
// f 131/141/131 230/240/230 231/242/231
0.167979223684599f, -0.0670168837233226f, 0.24286384937854f,
0.166391290343292f, -0.0686544011752973f, 0.241920432968569f,......
and many more.... But when i do this in a function or constructor i get a error while compiling that The code of method () is exceeding the 65535 bytes limit. So I was wondering if there is a different way to do this.
I tried storing the value in file and reading it back. But the IO operation, with string parsing of such huge record is very slow. Takes more than 60 sec. Which is not good.
Please let me know if there is any other way to do this. Thank you for your time and help.
But when i do this in a function or constructor i get a error while
compiling that The code of method () is exceeding the 65535 bytes
limit. So I was wondering if there is a different way to do this.
Put it outside the constructor (as a class variable or field)? If this doesn't change, just make it a constant. If it does change, make it a constant anyway and copy it in the constructor.
I tried storing the value in file and reading it back. But the IO
operation, with string parsing of such huge record is very slow. Takes
more than 60 sec. Which is not good.
If you do decide to keep it in an external file and read it in, don't read it as a string, just serialize it somehow (Java serialization, Protocol Buffers, etc.).
The program don't have to parse the float if we preprocess the data.
Write another program that write all float to a binary file using DataOutputStream.
In your program, read them back using DataInputStream. You might want to chain it with BufferedInputStream.
For this cases I normally use the assets folder to store files in binary format (even you can define some kind of file format to include the vertex, normals etc...) and allocate it on application initialization as wannik explains.
I would proprocess and store floats in binary form, then mmap it as byte buffer and create fload array out of it. This way you get float array, without parsing or allocation of space.