我的目标是从另一个文件中删除文件的内容,我可以通过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);
答案 0 :(得分:0)
将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是不可取的。
它实际上有点打字,但提供了一个只有一个责任的可靠工具。
答案 1 :(得分:0)
我尝试了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);
}
}
}