News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: .  (Read 5673 times)

creeperton

  • Hero Member
  • *****
  • Posts: 604
    • View Profile
.
« on: August 01, 2015, 01:12:48 pm »
.
« Last Edit: November 16, 2015, 01:57:33 am by creeperton »

PhOeNiX

  • Jr. Member
  • **
  • Posts: 74
    • View Profile
You need to iterate over the ZipEntries of the ZipInputStream.

Something like this:
Code: [Select]
ZipEntry entry;
while((entry=zis.getNextEntry())!=null){
//if we could gather the next zip entry, now, the zip input stream will allow reading the data associated to the current entry (i.e. the current file)...
// so just call zis.read(...)
// you may call entry.getName() and entry.getSize() to get the file name of the current file and its size.
}
zis.close();

So, you should iterate the zip entries, check with getName() whether it is the entry you want to read. Then, (assuming the file is not too big), create a byte array of length equal to entry.getSize(),
read with zis.read(...) the file content to the byte array, and finally write it to the output stream.
« Last Edit: August 01, 2015, 02:59:15 pm by PhOeNiX »

creeperton

  • Hero Member
  • *****
  • Posts: 604
    • View Profile
.
« Reply #2 on: August 02, 2015, 03:20:52 am »
.
« Last Edit: November 16, 2015, 01:57:27 am by creeperton »

PhOeNiX

  • Jr. Member
  • **
  • Posts: 74
    • View Profile
How big depends on your ram size. Otherwise, you don't need to divide it evenly, just construct a fixed size byte array. The method "read" of zis will return the number of bytes read.

You can iterate by calling "read" until it returns a negative number. There are plenty of tutorials about this online.

Check this for example: http://kodejava.org/how-do-i-decompress-a-zip-file-using-zipinputstream/

creeperton

  • Hero Member
  • *****
  • Posts: 604
    • View Profile
.
« Reply #4 on: August 08, 2015, 03:08:00 pm »
.
« Last Edit: November 16, 2015, 01:57:20 am by creeperton »

KaioShin

  • RHDN Patreon Supporter!
  • Hero Member
  • *****
  • Posts: 5697
    • View Profile
    • The Romhacking Aerie
What else do you want from a tutorial? It explains what the important idea is in the comment, the rest is all standard I/O code. It goes through all the entries and dumps each to a new file.


https://docs.oracle.com/javase/7/docs/api/java/io/FileInputStream.html

Code: [Select]
public int read(byte[] b, int off, int len)
// Reads up to len bytes of data from this input stream into an array of bytes.

Why does it return an int, and what does that int represent?  Does this method automatically update the current read location in the file, or must I keep track of that myself, as I tried to in the for loop at line 228?

It's all there on the site you even linked to.

Quote from: Oracle
Returns:
the total number of bytes read into the buffer, or -1 if there is no more data because the end of the file has been reached.
All my posts are merely personal opinions and not statements of fact, even if they are not explicitly prefixed by "In my opinion", "IMO", "I believe", or similar modifiers. By reading this disclaimer you agree to reply in spirit of these conditions.

PhOeNiX

  • Jr. Member
  • **
  • Posts: 74
    • View Profile
The main problem I see in your code is this:
Code: [Select]
if (zipEntry.getName() == "tempItemData")
Java's "==" operator performs a "pointer" equality check. In order to correctly compare two strings, you must use the "equals" method instead.
Code: [Select]
zipEntry.getName().equals("tempItemData")
I did not check the rest of the code, but as Kaioshin already said: everything you need to known is in the official javadoc. Just read it.

creeperton

  • Hero Member
  • *****
  • Posts: 604
    • View Profile
.
« Reply #7 on: August 10, 2015, 11:02:58 pm »
.
« Last Edit: November 16, 2015, 01:57:14 am by creeperton »

Seihen

  • Sr. Member
  • ****
  • Posts: 405
    • View Profile
Now, I could be stupid and not know what I'm talking about (totally likely) since I don't do any Java coding, but...

(ZipEntry zipEntry = zis.getNextEntry(); zipEntry != null;)

You're inconsistent with your capitalization of your variables. In most languages, ZipEntry and zipEntry would be different entities.
Did you check that?

henke37

  • Hero Member
  • *****
  • Posts: 643
    • View Profile
That's intentional. One is a class, the other is a variable holding a reference to an instance of the class.

Also, the hang issue is embarrassingly simple. You need to put the iteration code in the part of the loop that is actually repeated. The first part of the for statement is only run once, to initialize the loop.

creeperton

  • Hero Member
  • *****
  • Posts: 604
    • View Profile
.
« Reply #10 on: August 11, 2015, 04:20:09 pm »
.
« Last Edit: November 16, 2015, 01:56:52 am by creeperton »

KC

  • Full Member
  • ***
  • Posts: 209
    • View Profile
The fact that the buffer array is not quite 7168 bytes long is probably related. Really, read the documentation... http://docs.oracle.com/javase/7/docs/api/java/io/FileOutputStream.html#write%28byte[],%20int,%20int%29

creeperton

  • Hero Member
  • *****
  • Posts: 604
    • View Profile
.
« Reply #12 on: August 12, 2015, 08:36:15 pm »
.
« Last Edit: November 16, 2015, 01:56:26 am by creeperton »

KC

  • Full Member
  • ***
  • Posts: 209
    • View Profile
As was stated in the documentation I directly linked to...
Quote
public void write(byte[] b,
         int off,
         int len)

Parameters:
    b - the data.
    off - the start offset in the data.
    len - the number of bytes to write.
Try to see how far i*28 is from the start of the array you pass, for any given iteration...

creeperton

  • Hero Member
  • *****
  • Posts: 604
    • View Profile
.
« Reply #14 on: August 13, 2015, 05:16:00 pm »
.
« Last Edit: November 16, 2015, 02:01:47 am by creeperton »

Vehek

  • Full Member
  • ***
  • Posts: 176
    • View Profile
I haven't actually gotten around to trying to access binary files in Java, so I'm not too sure about how it'll work, but maybe RandomAccessFile would work better?

creeperton

  • Hero Member
  • *****
  • Posts: 604
    • View Profile
.
« Reply #16 on: August 13, 2015, 06:15:10 pm »
.
« Last Edit: November 16, 2015, 02:00:31 am by creeperton »

henke37

  • Hero Member
  • *****
  • Posts: 643
    • View Profile
Did you consider that the object may be tracking a "current position" in the file? I bet that there is a method to change that position.

KaioShin

  • RHDN Patreon Supporter!
  • Hero Member
  • *****
  • Posts: 5697
    • View Profile
    • The Romhacking Aerie
You are not supposed to randomly hop around in streams. Why? Because seeking back and forth on external memory like HDDs is slow as effing fuck (thousands of times slower than in memory). Hence why streams exist. They work linearily. You start and then work your way through it from start to finish without hopping back all the time. If you need to randomly access the data -> that's why you load the data into a buffer. That one is in memory and you can do what you want with it.

A stream object tracks its position by itself, there is no need to mess with it. If you need to, you are doing it wrong. If you check the documentation on File[Input/Output]Streams linked earlier in the thread you'll also notice that there are overloaded read/write methods that don't need any offsets and indicies, just a buffer and nothing else. Because the library can flush a stream into a buffer or vice versa by itself. It doesn't get any easier.
All my posts are merely personal opinions and not statements of fact, even if they are not explicitly prefixed by "In my opinion", "IMO", "I believe", or similar modifiers. By reading this disclaimer you agree to reply in spirit of these conditions.

creeperton

  • Hero Member
  • *****
  • Posts: 604
    • View Profile
.
« Reply #19 on: August 18, 2015, 12:40:45 am »
.
« Last Edit: November 16, 2015, 02:02:35 am by creeperton »