在下面的“编辑”部分中查看更新的问题
我正在尝试使用GZIPInputStream从Amazon S3快速解压缩大的(〜300M)GZIP文件,但它仅输出文件的一部分;但是,如果我在解压缩之前下载到文件系统,则GZIPInputStream将解压缩整个文件。
如何获得GZIPInputStream解压缩整个HTTPInputStream而不只是它的第一部分?
请参阅下面的编辑部分中的更新
我怀疑有一个HTTP问题,只是没有抛出任何异常,GZIPInputStream每次都返回一个相当一致的文件块,据我所知,它总是在WET记录边界上中断,尽管每个选择的边界都是不同的URL(这很奇怪,因为所有内容都被视为二进制流,根本没有对文件中的WET记录进行任何解析。)
我可以找到的最接近的问题 是,从s3读取时GZIPInputStream被过早关闭。该问题的答案是,某些GZIP文件实际上是多个附加的GZIP文件,而GZIPInputStream处理得不好。但是,如果是这种情况,为什么GZIPInputStream在文件的本地副本上可以正常工作?
下面是一段示例代码,演示了我所遇到的问题。我已经在两个不同网络上的两台不同Linux计算机上使用Java 1.8.0_72和1.8.0_112对它进行了测试,结果相似。我希望来自解压缩的HTTPInputStream的字节数与来自文件的解压缩的本地副本的字节数相同,但是经过解压缩的HTTPInputStream小得多。
输出量Testing URL https://commoncrawl.s3.amazonaws.com/crawl-data/CC-MAIN-2016-50/segments/1480698540409.8/wet/CC-MAIN-20161202170900-00009-ip-10-31-129-80.ec2.internal.warc.wet.gz
Testing HTTP Input Stream direct to GZIPInputStream
Testing saving to file before decompression
Read 87894 bytes from HTTP->GZIP
Read 448974935 bytes from HTTP->file->GZIP
Output from HTTP->GZIP saved to file testfile0.wet
------
Testing URL https://commoncrawl.s3.amazonaws.com/crawl-data/CC-MAIN-2016-50/segments/1480698540409.8/wet/CC-MAIN-20161202170900-00040-ip-10-31-129-80.ec2.internal.warc.wet.gz
Testing HTTP Input Stream direct to GZIPInputStream
Testing saving to file before decompression
Read 1772936 bytes from HTTP->GZIP
Read 451171329 bytes from HTTP->file->GZIP
Output from HTTP->GZIP saved to …Run Code Online (Sandbox Code Playgroud) 使用以下Java代码将字节[]压缩/解压缩到GZIP或从GZIP解压缩.第一个文本字节为gzip字节:
public static byte[] fromByteToGByte(byte[] bytes) {
ByteArrayOutputStream baos = null;
try {
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
baos = new ByteArrayOutputStream();
GZIPOutputStream gzos = new GZIPOutputStream(baos);
byte[] buffer = new byte[1024];
int len;
while((len = bais.read(buffer)) >= 0) {
gzos.write(buffer, 0, len);
}
gzos.close();
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
return(baos.toByteArray());
}
Run Code Online (Sandbox Code Playgroud)
然后将压缩字节转换为未压缩字节的方法:
public static byte[] fromGByteToByte(byte[] gbytes) {
ByteArrayOutputStream baos = null;
ByteArrayInputStream bais = new ByteArrayInputStream(gbytes);
try {
baos = new ByteArrayOutputStream();
GZIPInputStream gzis = …Run Code Online (Sandbox Code Playgroud) 我是Java新手.我想学习使用GZIPstreams.我已经尝试过这个:
ArrayList<SubImage>myObject = new ArrayList<SubImage>(); // SubImage is a Serializable class
ObjectOutputStream compressedOutput = new ObjectOutputStream(
new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream(
new File("....")))));
compressedOutput.writeObject(myObject);
Run Code Online (Sandbox Code Playgroud)
和
ObjectInputStream compressedInput = new ObjectInputStream(
new BufferedInputStream(new GZIPInputStream(new FileInputStream(
new File("....")))));
myObject=(ArrayList<SubImage>)compressedInput.readObject();
Run Code Online (Sandbox Code Playgroud)
当程序写入myObject文件时不会抛出任何异常,但是当它到达该行时
myObject=(ArrayList<SubImage>)compressedInput.readObject();
Run Code Online (Sandbox Code Playgroud)
它抛出此异常:
Exception in thread "main" java.io.EOFException: Unexpected end of ZLIB input stream
Run Code Online (Sandbox Code Playgroud)
我怎么解决这个问题?
我有以下代码来压缩和解压缩字符串.
public static byte[] compress(String str)
{
try
{
ByteArrayOutputStream obj = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(obj);
gzip.write(str.getBytes("UTF-8"));
gzip.close();
return obj.toByteArray();
}
catch (IOException e)
{
e.printStackTrace();
}
return null;
}
public static String decompress(byte[] bytes)
{
try
{
GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(bytes));
BufferedReader bf = new BufferedReader(new InputStreamReader(gis, "UTF-8"));
StringBuilder outStr = new StringBuilder();
String line;
while ((line = bf.readLine()) != null)
{
outStr.append(line);
}
return outStr.toString();
}
catch (IOException e)
{
return e.getMessage();
} …Run Code Online (Sandbox Code Playgroud) 我有一个包含gzip压缩日志文件的目录,每行一个事件.为了实时读取和处理这些,我创建了一个与此处列出的代码相同的WatcherService:http://docs.oracle.com/javase/tutorial/essential/io/notification.html
在processEvents()方法中,我添加了此代码以逐行读取已添加或追加的文件:
if (kind == ENTRY_MODIFY) {
try(BufferedReader reader = new BufferedReader(new InputStreamReader(new GZIPInputStream(Files.newInputStream(child, StandardOpenOption.READ))))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
catch(EOFException ex) {
//file is empty, so ignore until next signal
}
catch(Exception ex) {
ex.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
现在,正如您可以想象的那样,这对于在几毫秒内创建的已编写和关闭的文件非常有用,但是,当处理随时间附加的大文件时,这将为每个附加行反复读取整个文件(给定生成器现在然后刷新和同步文件).
有没有什么办法可以在每次发送ENTRY_MODIFY信号时只读取此文件中的新行,或者找出文件"完成"的时间?
如何处理未附加但被覆盖的文件?
如何解压缩由PHP gzcompress()函数压缩的字符串?
有完整的例子吗?
谢谢
我现在尝试了这样:
public static String unzipString(String zippedText) throws Exception
{
ByteArrayInputStream bais = new ByteArrayInputStream(zippedText.getBytes("UTF-8"));
GZIPInputStream gzis = new GZIPInputStream(bais);
InputStreamReader reader = new InputStreamReader(gzis);
BufferedReader in = new BufferedReader(reader);
String unzipped = "";
while ((unzipped = in.readLine()) != null)
unzipped+=unzipped;
return unzipped;
}
Run Code Online (Sandbox Code Playgroud)
但是如果我正在尝试解压缩PHP gzcompress(-ed)字符串,它就无法正常工作.
我有一个奇怪的程序,GzipInputStream零填充缓冲区的一部分.我有幸知道流中的字节应该是什么样的,我可以看到缓冲区正在填充8个正确的字节和12个零(不应该为零)
BYTES应该看起来像这样----> 0 20 82 22 -91 27 -96 65 66 65 88 32 32 32 32 81 32 0 0 0 100 78
BYTES实际上看起来像这样---> 0 20 82 22 -91 27 -96 65 66 65 0 0 0 0 0 0 0 0 0 0 0 0
前两个字节表示一个整数,用于确定前两个字节之后的可变长度(以字节为单位)的大小.所以在这个例子中,第一个字节是0 20,而在BIG_ENDIAN中,这给我们后续的有效载荷大小为20个字节.
这是我的阅读代码
gzipInputStream = new GZIPInputStream(url.openStream());
byte[] payload = new byte[2];
gzipInputStream.read(payload);
for(int i=0;i<payload.length;i++){
System.out.println(payload[i]);
}
int payloadSize = ((payload[0] & 0xFF) << 8) | ((payload[1]) & 0xFF);
//read the next payloadSize …Run Code Online (Sandbox Code Playgroud) 我搜索了一个如何在Java中压缩字符串的示例。
我有一个压缩然后解压缩的功能。压缩似乎可以正常工作:
public static String encStage1(String str)
{
String format1 = "ISO-8859-1";
String format2 = "UTF-8";
if (str == null || str.length() == 0)
{
return str;
}
System.out.println("String length : " + str.length());
ByteArrayOutputStream out = new ByteArrayOutputStream();
String outStr = null;
try
{
GZIPOutputStream gzip = new GZIPOutputStream(out);
gzip.write(str.getBytes());
gzip.close();
outStr = out.toString(format2);
System.out.println("Output String lenght : " + outStr.length());
} catch (Exception e)
{
e.printStackTrace();
}
return outStr;
}
Run Code Online (Sandbox Code Playgroud)
但是相反的是,即使我将encStage1的返回结果直接传递回decStage3,也抱怨该字符串不是GZIP格式:
public static String decStage3(String str)
{
if …Run Code Online (Sandbox Code Playgroud) java ×7
gzip ×4
compression ×2
amazon-s3 ×1
android ×1
binary ×1
c# ×1
gzipstream ×1
inputstream ×1
stream ×1