【问题标题】:Delete N bytes from the end of an inputstream从输入流的末尾删除 N 个字节
【发布时间】:2016-08-10 15:10:25
【问题描述】:

我的目标是从另一个文件中删除一个文件的内容,我可以通过 HttpURLConnection 访问这些文件。

我的想法是从第一个文件中获取内容长度,我们将这个内容长度称为 N。并从第二个输入流(file2)中删除N个字节。

HttpURLConnection connection1 = (HttpURLConnection) url1.openConnection();
HttpURLConnection connection2 = (HttpURLConnection) url2.openConnection();

String contentLength1 = connection1.getHeaderFields().get("Content-Length").get(0);
String contentLength2 = connection2.getHeaderFields().get("Content-Length").get(0);
InputStream is = connection2.getInputStream();

编辑:

我找到了办法,不知道有没有更好的办法。

ByteArrayOutputStream into = new ByteArrayOutputStream();
byte[] buf = new byte[4096];

for (int n; 0 < (n = is.read(buf));) {
    into.write(buf, 0, n);
}
into.close();

byte[] data = into.toByteArray();
int length1 = Integer.parseInt(contentLength1);
int length2 = Integer.parseInt(contentLength2);
byte[] newData = new byte[length2-length1];

System.arraycopy(data, 0, newData, 0, newData.length);
ByteArrayInputStream newStream = new ByteArrayInputStream(newData);

【问题讨论】:

  • 请标记您的平台。还请说明到目前为止您所尝试的问题,因为问题太宽泛了 - 请参阅stackoverflow.com/help/how-to-ask
  • @Yassine 你在用 Java 编码吗?这是我所知道的唯一一种在标准库中包含 HttpURLConnection 类的流行语言。请出示相关代码供我们帮助。
  • 我编辑了我的问题以提供有关我的问题的更多信息

标签: java byte inputstream httpurlconnection


【解决方案1】:

将您的 InputStream 包装在一个只读取所需长度的类中。

class TruncatedInputStream extends InputStream {

    private final InputStream in;
    private final long maxLength;
    private long position;

    TruncatedInputStream(InputStream in, long maxLength) ... {
        this.in = in;
        this.maxLength = maxLength;
    }

    @Override
    int read() ... {
        if (position >= maxLength) {
            return -1;
        }
        int ch = in.read();
        if (ch != -1) {
            ++position;
        }
        return -1;
    }
}

思维跳跃,重置。使用 BufferedInputStream 并非不可取。

实际上它需要更多的输入,但提供了一个可靠的工具,只有一个职责。

【讨论】:

    【解决方案2】:

    我尝试了 existing answer,但它对我不起作用 - 特别是我看不到 read 方法如何返回 -1 以外的任何值。

    我用以下内容对其进行了扩展:

    /**
     * Truncates a {@link java.io.InputStream} to a specified number of bytes. <br>
     * <br>
     * Based on <a href="https://stackoverflow.com/a/38891920">this implementation</a>. <br>
     * <br>
     * <a href="https://stackoverflow.com/a/52149547">Source</a>.
     */
    public class TruncatedInputStream extends InputStream
    {
        private final InputStream inputStream;
        private final long maxLengthInBytes;
        private long position;
    
        /** @see TruncatedInputStream */
        public TruncatedInputStream(final InputStream inputStream, final long maxLengthInBytes)
        {
            this.inputStream = inputStream;
            this.maxLengthInBytes = maxLengthInBytes;
        }
    
        @Override
        public int read() throws IOException
        {
            return position++ < maxLengthInBytes ? inputStream.read() : -1;
        }
    }
    

    另外,我写了一个单元测试:

    public class TruncatedInputStreamTest
    {
        @Test
        public void testTruncatedInputStream() throws IOException
        {
            byte[] input = new byte[] {};
            doTest(input, new byte[] {}, 1);
            doTest(input, new byte[] {}, 0);
    
            input = new byte[] {0};
            doTest(input, new byte[] {0}, 1);
            doTest(input, new byte[] {}, 0);
    
            input = new byte[] {0, 1};
            doTest(input, new byte[] {0, 1}, 3);
            doTest(input, new byte[] {0, 1}, 2);
            doTest(input, new byte[] {0}, 1);
            doTest(input, new byte[] {}, 0);
    
            input = new byte[] {0, 1, 2};
            doTest(input, new byte[] {0, 1, 2}, 3);
            doTest(input, new byte[] {0, 1}, 2);
            doTest(input, new byte[] {0}, 1);
            doTest(input, new byte[] {}, 0);
        }
    
        private void doTest(final byte[] input, final byte[] expectedOutput, final long length) throws IOException
        {
            try (PipedInputStream pipedInputStream = new PipedInputStream(); InputStream truncatedInputStream = new TruncatedInputStream(pipedInputStream, length))
            {
                try (OutputStream outputStream = new PipedOutputStream(pipedInputStream))
                {
                    IOUtils.write(input, outputStream);
                }
    
                final byte[] actualOutput = IOUtils.toByteArray(truncatedInputStream);
    
                assertArrayEquals(Arrays.toString(actualOutput), expectedOutput, actualOutput);
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-28
      • 1970-01-01
      • 2012-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多