• (disco)

    This dude made every attempt to use all the different types of object capable of holding a byte (or array of Byte), didn't he? Not only that, but it looks like they're buffering up to five times as well (input stream, byte array, vector, buffered output stream, and output stream)....

    Oh well, it's a great way to test the GC efficiency as well as memory capacity.

  • (disco)

    Given how common a task it is to copy one stream to another, it's amazing how many frameworks don't support it out of the box. Or at least, not for all scenarios; Java 7 at least has one that would be exceptionally useful for the article's codemonkey:

    Files.copy(InputStream in, Path target)
    

    Edit: OK, there is one framework at least that has a fit-for-all solution: .NET. They added it in v4.0.

  • (disco)

    LPT: When you see Java code using Vector, it's probably going to be a WTF. Also, this code seems like a copy&paste example from reading an InputStream in Java 1.4.

  • (disco) in reply to Eldelshell
    Eldelshell:
    When you see Java code using Vector, it's probably going to be a WTF.

    True; it should really be using ArrayList :trolleybus:

  • (disco) in reply to RaceProUK

    Well that's in the Tcl language core [fcopy] :-) so it doesn't have to be in any framwork Tcl/Tk uses. More general there as well than the example you give: fcopy inchan outchan ?-size size? ?-command callback?

    Where things in ??'s are optional.
    http://www.tcl.tk/man/tcl8.5/TclCmd/fcopy.htm

    Someone will, no doubt remind me this is about an android project so I have to a dd the link:

    http://www.androwish.org/index.html/home

  • (disco)

    Don't forget, the code doesn't even use try-with-resources. One exception and who knows when those streams will be closed...

    On a related note, why do so few languages have deterministic destructors?

  • (disco) in reply to LB_
    LB_:
    On a related note, why do so few languages have deterministic destructors?
    If you're talking about languages with garbage collectors, then garbage collectors ;)
  • (disco)
    RaceProUK:
    True; it should really be using ArrayList :trolleybus:

    Shouldn't he have used a linked list of bytes instead?

    RaceProUK:
    garbage collectors

    Where I live, the garbage collectors are scheduled for every Tuesday. (Except when Monday or Tuesday is a public holiday.)

    Once a week should do for most systems. If not, get a bigger bin.

    while ((line = inputReader.readLine()) != null) { output.write(line + "\n"); }

    As Unix tradition dictates, All Data Are Plain Text.

  • (disco)
     BufferedReader inputReader = new BufferedReader(new InputStreamReader(in));
    

    File destination = new File(fileName); FileWriter output = new FileWriter(destination) String line; while ((line = inputReader.readLine()) != null) { output.write(line + "\n"); }

    This is quite WTFy itself. The original code reads binary data, where this is reading in text. You're not specifying the charset to be used, i.e. the system-charset is used and might lead to corrupt text (e.g. on systems with ASCII as charset - yes, they are still out there). When reading in binary data, all single occurrances of carriage return and carriage return/new line will be replaced by newline alone, corrupting binary data will the file appear in Notepad on one line. And if the data being read happens to have a data-block bigger that 16 KB without any line breaks, writing this block might lead to an IOException (that depends on the virual machine in use).

    A home made file copy might look like this:

    public static void copyData(InputStream is, OutputStream os){ byte[] buf = new byte[4096]; int read; while ((read = is.read(buf)) != -1){ os.write(buf, 0, read); } }

    The closing of the streams is delegated to the caller in this place.

  • (disco) in reply to lkimmerin
    lkimmerin:
    The closing of the streams is delegated to the caller in this place.
    As it should be; the only API that should close a stream is the `Close()` method
  • (disco) in reply to RaceProUK

    Wow. A decade ago I was wondering why there was no mechanism in Java to connect two Streams. Sure, a byte-pusher loop was easy to write, but it felt like I was missing a basic function somewhere. It's like expecting your plumber to cast the pipes herself.

  • (disco)

    I'm concerned there's no range checking. Surely you should make sure that the data you are reading is within the range of the elements you're transferring them via?

    for (int i = 0; i < 1024; i++) {
        if (tmpByteArray[i] < 0) throw new Exception("oh bother");
        if (tmpByteArray[i] > 128) throw new Exception("oh bother again");
    }
    
    for (int i = 0; i < r; i++) {
    	vector.add(Byte.valueOf(tmpByteArray[i]));
    }
    
    
  • (disco) in reply to RaceProUK
    RaceProUK:
    lkimmerin:
    The closing of the streams is delegated to the caller in this place.
    As it should be; the only API that should close a stream is the `Close()` method

    AndPlus I think any stream should be closed in the same procedure where it has been opened. (anything else I declare a :wtf:)

  • (disco) in reply to Quite

    Añy òñë whô usës Éxtëndèd ÅSCII ìs dòîng ìt wróng.

  • (disco) in reply to Placeholder

    Exactly; we should all be using Unicode :stuck_out_tongue:

  • (disco) in reply to Placeholder

    EBCDIC. (more characters to make the minimum post size)

  • (disco) in reply to lkimmerin
    lkimmerin:
    You're not specifying the charset to be used, i.e. the system-charset is used and might lead to corrupt text (e.g. on systems with ASCII as charset - yes, they are still out there).
    Paging @Yamikuronue : using `InputStreamReader` without an encoding parameter really is a potential source of encoding problems.

    I know you were shooting for "it looked something like this", but I wanted to highlight this after having this problem cause trouble in production code.

  • (disco) in reply to RFoxmich
    RFoxmich:
    (more characters to make the minimum post size)

    didn't we turn that down to 1?

    are you sure you didn't get the "more descriptive" error you get when you don't have at least one lower case letter (HTML tags count because :wtf:)?

  • (disco) in reply to accalia

    Unicode is most extended ASCII in use (and probably existence).

    @Quite: In Java, bytes are signed, like every other numeric type, so the valid range is -128 to 127. Your code will never throw "oh bother again". Even if you're being sarcastic, your upper bound is off by 1, as 128 is not a valid byte value. The "oh bother" exception is even more problematic, since you're rejecting half of the valid range without giving a reason.

  • (disco) in reply to Khudzlin
    Khudzlin:
    Even if you're being sarcastic, your upper bound is off by 1, as 128 is not a valid byte value.
    Not really an issue; in those comparisons, the operands are probably being upcast to `int` anyway
  • (disco)

    I haven't used Java for a long time but I swear you can just hook streams together to pipe them.

    Perhaps it was this:

    http://docs.oracle.com/javase/7/docs/api/java/io/PipedInputStream.html

    But as usual there's no way to create it from an InputStream except something ugly like a cast. Thanks java.

  • (disco) in reply to LB_
    LB_:
    Don't forget, the code doesn't even use try-with-resources. One exception and who knows when those streams will be closed...
    But (external factors aside) at least he'll never end up with an incomplete file.
  • (disco) in reply to JBert
    JBert:
    using InputStreamReader without an encoding parameter really is a potential source of encoding problems.

    Thanks :) I'll put in an update today. I think I actually took that sample from part of my download code for a known API endpoint, so I knew the encoding wouldn't cause issues in advance, but being specific is always useful for future enhancements.

  • (disco) in reply to urkerab
    urkerab:
    at least he'll never end up with an incomplete file.

    Tell that to my flash drive.

  • (disco) in reply to gleemonk
    gleemonk:
    A decade ago I was wondering why there was no mechanism in Java to connect two Streams.

    It would be bad.

    http://ckmacleod.com/wp-content/uploads/2014/03/ghostbusters-cross-the-streams.jpg

  • (disco) in reply to isthisunique

    A quick search turned up third-party libraries only. And this is a decade later!

    isthisunique:
    But as usual there's no way to create it from an InputStream except something ugly like a cast. Thanks java.

    Wouldn't the cast fail? I guess you could write some facades to use your InputStream as a PipedInputStream, and your OutputStream as a PipedOutputStream

    new PipedInputStreamForInputStream(in).connect(new PipedOutputstreamForOutPutStream(out));
    

    :innocent:

  • (disco) in reply to PWolff
    PWolff:
    Shouldn't he have used a linked list of bytes instead?

    I came across an effort by a new programmer where there was a list of single-letter codes and another list of short text codes (country codes e.g. GB). So he put the letter codes into a linked list, the text codes into a linked list, and the two linked lists into an ArrayList. Because...he had just discovered linked lists. So - it's been done.

  • (disco) in reply to RaceProUK

    Indeed they are, as per Java specifications. That's not the issue. Since Java bytes are signed, there won't be any value over 127 in the first place. But even if the first operand could somehow be over 127, the test would fail to reject 128 (which is outside of the signed byte range). The first test would make sense only if testing for strict ASCII. Since that is not part of the requirements, it unnecessarily fails when reading anything other than ASCII data (binary, extended ASCII, Unicode).

  • (disco) in reply to boomzilla

    :scream: What happened?

  • (disco) in reply to gleemonk
    gleemonk:
    new PipedInputStreamForInputStream(in).cross(new PipedOutputstreamForOutPutStream(out));
    

    GTFY

  • (disco) in reply to gleemonk
    gleemonk:
    new PipedInputStreamForInputStream(in).connect(new PipedOutputstreamForOutPutStream(out));
    
    I especially like the messed up CamelCase.
  • (disco) in reply to Gaska
    Gaska:
    I especially like the messed up CamelCase.PascalCase

    FTFY

    and yes i did read your mouseover text. That's why i bothered to correct you!

  • (disco) in reply to accalia

    You must have not read it to the end.

  • (disco) in reply to Gaska

    CapitalizedCamelCase is not a thing, the correct name for what you describe is PascalCase.

    :tangerine:

  • (disco) in reply to accalia

    Gąska refers to Outputstream vs. OutPutStream (within the same class name too), obviously.

    Or did I miss a joke?

  • (disco) in reply to Khudzlin

    Continuing the discussion from Byte me:

    Khudzlin:
    Unicode is most extended ASCII in use (and probably existence).

    @Quite: In Java, bytes are signed, like every other numeric type, so the valid range is -128 to 127. Your code will never throw "oh bother again". Even if you're being sarcastic, your upper bound is off by 1, as 128 is not a valid byte value. The "oh bother" exception is even more problematic, since you're rejecting half of the valid range without giving a reason.

    Yes, exactly. I deliberately put together the stupidest (and indeed completely pointless) error checking code I could, deliberately mucking up the limits of the maxbyte field, not to mention the WTFery going on at the bottom. I was expecting the reaction to be something like, "No, you should put the test into a j loop cycling from 0 to i" or something.

    I once had to maintain a program which was choking somewhere on some invalid data, and the only help I got was a message when it exited saying "oh bother" except the word wasn't "bother" it was something NSFW which started and finished the same. It took me half a day to trap down all the places where the problem could have been caused and replace it with a proper error check and so to report exactly what the problem was. The fact that the program ran for 3 hours before the problem was encountered was just the icing on the festival-weekend cake.

  • (disco) in reply to accalia
    accalia:
    CapitalizedCamelCase is not a thing, the correct name for what you describe is PascalCase.
    Whoosh.
    PWolff:
    Gąska refers to Outputstream vs. OutPutStream (within the same class name too), obviously.
    This too. But you still missed the PascalCase one.
  • (disco) in reply to Gaska
    Gaska:
    Whoosh.

    if i get another fucking whoosh badger for that i am going to scream, record myself screaming and send you the uncompressed 88.4khz 32bit PCM .wav of that scream.

  • (disco) in reply to Gaska
    Gaska:
    you still missed the PascalCase one

    Probably. I don't really care so much about those names.

    Gaska:
    CamelCase is actually the one that starts with small letter

    Can't be. Otherwise it would be named camelCase.

  • (disco) in reply to accalia

    Also -

    accalia:
    CapitalizedCamelCase is not a thing
    [There's at least one person in the universe that used that term before me.](https://groups.google.com/forum/#!topic/cfwheels/oJsLLq3kCtE)
  • (disco) in reply to Gaska
    Gaska:
    There's at least one person in the universe that used that term before me.

    There's also at least one person in the universe that used the term "noodle" in relation to code.

    Doesn't make it a sensible term, now does it?

  • (disco) in reply to Gaska

    Err i uM my shift keys have considerable lag at the relativistic speeds i'm tyPing things

  • (disco) in reply to RaceProUK
    RaceProUK:
    Given how common a task it is to copy one stream to another, it's amazing how many frameworks don't support it out of the box.

    In fact, that results (at least in the Java ecosystem) that every little framework (Google Guava, Apache Commons, ...) will at some place will have a IOUtils.copy method (that is interestingly almost everywhere named exactly this way, only the package name differs; except Guava who calls it ByteStreams.copy). In fact, I once took a larger project that depended on 20 or so open source libraries, and did an Eclipse search for methods called IOUtils.copy, and found (if I remember correctly) 5 of them in different packages.

  • (disco) in reply to Maciejasjmj
    Maciejasjmj:
    There's also at least one person in the universe that used the term "noodle" in relation to code.

    Doesn't make it a sensible term, now does it?

    I wasn't saying it's sensible.
  • (disco) in reply to gleemonk
    gleemonk:
    Err i uM my shift keys have considerable lag at the relativistic speeds i'm tyPing things

    /me makes a note to remember that excuse when she gets called out on her tyops next time

  • (disco) in reply to gleemonk

    Would probably fail yes but it's been a long time :D. If I remember you can only cast it to something it actually is.

    The fascade defeats the point really.

  • (disco) in reply to kupfernigk

    This is called using whatever we learned in class today.

  • (disco) in reply to accalia
    accalia:
    fucking whoosh badger

    Briefly — very briefly — tempted to see if GIS turned up anything amusing for that. But then I recovered what little sanity I have left, and decided *NO*!!!!!

    accalia:
    .wav of that scream
    [image]
  • (disco) in reply to accalia

    On 5 1/4" floppy disks, right?

    Fox screams are kinda creepy though... (Waits for the :giggity: ...)

  • (disco) in reply to HardwareGeek
    HardwareGeek:
    Briefly — very briefly — tempted to see if GIS turned up anything amusing for that. But then I recovered what little sanity I have left, and decided *NO*!!!!!

    /me also is briefly curious before self defense circuits cut in and excise the curiosity

    HardwareGeek:
    accalia:
    .wav of that scream
    [image]
    It's amazing the motivation power a well placed and precise promise can get you.

    Yes i will do it, yes it will be a .wav file, although if you ask really nicely i may be convinced to instead remove the .wav header and give you an unannotated .pcm file instead.

Leave a comment on “Byte me”

Log In or post as a guest

Replying to comment #:

« Return to Article