-2

Can someone help me figure out what I am doing wrong here? This method does nothing except produce empty lines when calling new InputStreamReader(stream, getSet(stream);

Thank you all!

private static final byte[] UTF8_BOM = new byte[] {(byte) 0xEF, (byte) 0xBB, (byte) 0xBF};

private static final byte[] UTF16LE_BOM = new byte[] {(byte) 0xFF, (byte) 0xFE};

private static final byte[] UTF16BE_BOM = new byte[] {(byte) 0xFE, (byte) 0xFF};

public static Charset getSet(final InputStream stream) throws IOException {

        final byte[] UTF8_Buffer = new byte[3];
        final byte[] UTF16LE_Buffer = new byte[2];
        final byte[] UTF16BE_Buffer = new byte[2];
        int byteValue;
        InputStream bufferedStream = new BufferedInputStream(stream);
        bufferedStream.mark(3);

        byteValue = stream.read();

        UTF16LE_Buffer[0] = (byte) byteValue;
        UTF16BE_Buffer[0] = (byte) byteValue;
        UTF8_Buffer[0] = (byte) byteValue;

        byteValue = bufferedStream.read();
        UTF16LE_Buffer[1] = (byte) byteValue;
        UTF16BE_Buffer[1] = (byte) byteValue;
        UTF8_Buffer[1] = (byte) byteValue;
        if (Arrays.equals(UTF16LE_Buffer, UTF16LE_BOM)) {
          return StandardCharsets.UTF_16LE;
        } else if (Arrays.equals(UTF16BE_Buffer, UTF16LE_BOM)) {
          return StandardCharsets.UTF_16BE;
        } else {
          byteValue = bufferedStream.read();
          UTF8_Buffer[2] = (byte) byteValue;
          if (Arrays.equals(UTF8_Buffer, UTF8_BOM)) {
            return StandardCharsets.UTF_8;
          }
        }

        bufferedStream.reset();
        return StandardCharsets.UTF_8;
      }
user207421
  • 305,947
  • 44
  • 307
  • 483

2 Answers2

1

The problem here is that you have already read two or three bytes from the input stream with the BufferedInputStream. Calling mark()/reset() on the BufferedInputStream allows you to reread those bytes from the BufferedInputStream, but it doesn't do anything to the underlying stream.

You should change the caller of this method to pass a BufferedInputStream instead of an InputStream, and remove the new BufferedInputStream from inside the method, so that the caller and the callee are both marking/resetting the same stream. If the caller doesn't pass an InputStream that supports mark()/reset(), calling either of those will throw an exception.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Is there any other solution? I am supposed to be programming to interfaces, or Abstract super classes in the case of InputStreams. Plus it doesn't look like BufferedInputStream supports file paths as input? – salvadore-jefferson Nov 16 '15 at 23:16
  • Well let me put it another way, see edit. You can do `new BufferedInputStream(new FileInputStream(...))`. – user207421 Nov 16 '15 at 23:48
  • This worked for the one aspect of my assignment, but it broke all my unit tests where I was calling the method with ByteArrayInputStream. I know I am on the wrong track when my existing unit test fail after refactoring. For the most part. But thanks for the tip, it did work how you said it would. – salvadore-jefferson Nov 17 '15 at 00:04
  • Why would it break your unit tests? `ByteArrayInputStream ` supports mark/reset. – user207421 Nov 17 '15 at 00:23
  • Because I changed the method signature from readText(InputStream) to readText(BufferedInputStream) So I could no longer call readText(ByteArrayInputStream) – salvadore-jefferson Nov 17 '15 at 00:26
  • So don't do that. I removed that part of my answer 3/4 of an hour ago. – user207421 Nov 17 '15 at 00:35
-2

I found a solution to my issue.

I changed the method from this:

public static String readText(@Nonnull final InputStream stream) throws IOException {
     try (final Reader reader = new InputStreamReader(stream, getCharset(stream))) {....

To this:

public static String readText(@Nonnull final InputStream stream) throws   IOException {
    final BufferedInputStream bufferedStream = new BufferedInputStream(stream);
    try (final Reader reader = new InputStreamReader(bufferedStream, getCharset(bufferedStream))) {...

Thanks for all the help folks!

  • You didn't 'find' a solution to your issue. I provided it. And you should accept and/or upvote any answers you find useful. And this answer contains changes to code you've never posted before. Not useful, and somewhat irritating. – user207421 Nov 18 '15 at 01:08