**********看看这个GZ解压代码的问题************

xql80329 2009-01-08 11:44:25


import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.GZIPInputStream;

public class GZIPcompress {
public static void main(String[] args) {
args[0]="aaaa.gz";
try{

if (args.length == 0) {
System.out.println("usage: java expandgz filename.gzzzzzzzzzz");
System.exit(0); }
GZIPInputStream gzi = new GZIPInputStream(new FileInputStream(args[0]));
int to = args[0].lastIndexOf('.');
if (to == -1) {
System.out.println("usage: java expandgz filename.gz");
System.exit(0); }
String fout = args[0].substring(0, to);

BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(fout) );
System.out.println("writing " + fout);
int b;
do {
b = gzi.read();
if (b==-1) break;
bos.write(b);
} while (true);
gzi.close();
bos.close();

}catch(Exception e){
e.printStackTrace();

}
}
}


红色那行 一直报数组越界呢 ?同时再问一下 关于GZ解压 有什么好办法没?
我的这个文件有几百M !谢谢!
...全文
652 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
liky5387 2009-01-09
  • 打赏
  • 举报
回复
关于GZ的解压,楼上已经再有挺多朋友帮你解决了,这里我就不多说了。

关于大文的读写,可以用NIO来理正理。NIO的内存映像文件可以处理大文件的读写。
我在网上整理出来一些资料,你可以看一下。
http://blog.csdn.net/lky5387/archive/2009/01/09/3739095.aspx

关于你的红色的地方报错的问题,可以你对main(String[] args)方法的理解上有一点的偏差。
他这个String类型的数组,是指的你的运行这个main方法时给出的参数:
比如说:在命令提示行下
c:\>java GZIPcompress "aaaa.gz"
这时,在你的main方法中就可以用直接使用了,这时的就等于"aaaa.gz"。它并不是给你声明了一个数组。
有多个参数,以空格分开。
c:\>java GZIPcompress "aaaa.gz" "aaa" "bbb" "ccc"
这里的args[0],args[1],args[2],args[3]就分别是"aaaa.gz"、"aaa"、"bbb"、"ccc"。

如果用的是eclipse来启动程序,那用:
点菜单上的:run->open run dialog...在Run对话筐中,点击(x)=Arguments选项卡,在Program arguments里真上的要参数就可以了。多个参数用空格分开。

xql80329 2009-01-09
  • 打赏
  • 举报
回复
我的问题就是下面这个说明
 // Nothing in the buffer. We need to know whether or not
// there is unread data available in the underlying stream
// since the base class will not handle an empty file.
// Read a byte to see if there is data and if so,
// push it back onto the stream...
byte[] b=new byte[1];
int ret=in.read(b,0,1);
if (ret==-1)
{
eos=true;
return -1;
}
xql80329 2009-01-09
  • 打赏
  • 举报
回复
同时我也在想为什么网上提供的方法都是一成不变的用那个类去解压呢?
xql80329 2009-01-09
  • 打赏
  • 举报
回复
问题终于解决了

看完后 要加精哦
是因为 SUN 提供的GZIPInputStream 这个类有严重BUG

在一个国外的网站上看到关于这个类一些说明
并且有个强人 把该类重写了
下面这个连接有详细的说明
http://203.208.37.104/search?q=cache:kW3ALlEjywIJ:bugs.sun.com/bugdatabase/view_bug.do%3Fbug_id%3D4691425+GZIPInputStream+read()&hl=zh-CN&ct=clnk&cd=14&gl=cn&st_usg=ALhdy2_cgCeMysBXbqifs3gMxzQMfhufnA

同时我把重写的那个类贴出来  请不要走弯路
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.io.IOException;

public
class MultiMemberGZIPInputStream extends GZIPInputStream {

public MultiMemberGZIPInputStream(InputStream in, int size) throws IOException
{
// Wrap the stream in a PushbackInputStream...
super(new PushbackInputStream(in, size), size);
this.size=size;
}

public MultiMemberGZIPInputStream(InputStream in) throws IOException
{
// Wrap the stream in a PushbackInputStream...
super(new PushbackInputStream(in, 1024));
this.size=-1;
}

private MultiMemberGZIPInputStream(MultiMemberGZIPInputStream parent) throws IOException
{
super(parent.in);
this.size=-1;
this.parent=parent.parent==null ? parent : parent.parent;
this.parent.child=this;
}

private MultiMemberGZIPInputStream(MultiMemberGZIPInputStream parent, int size) throws IOException
{
super(parent.in, size);
this.size=size;
this.parent=parent.parent==null ? parent : parent.parent;
this.parent.child=this;
}

private MultiMemberGZIPInputStream parent;
private MultiMemberGZIPInputStream child;
private int size;
private boolean eos;

public int read(byte[] inputBuffer, int inputBufferOffset, int inputBufferLen) throws IOException {

if (eos) { return -1;}
if (this.child!=null)
return this.child.read(inputBuffer, inputBufferOffset, inputBufferLen);

int charsRead=super.read(inputBuffer, inputBufferOffset, inputBufferLen);
if (charsRead==-1)
{
// Push any remaining buffered data back onto the stream
// If the stream is then not empty, use it to construct
// a new instance of this class and delegate this and any
// future calls to it...
int n = inf.getRemaining() - 8;
if (n > 0)
{
// More than 8 bytes remaining in deflater
// First 8 are gzip trailer. Add the rest to
// any un-read data...
((PushbackInputStream)this.in).unread(buf, len-n, n);
}
else
{
// Nothing in the buffer. We need to know whether or not
// there is unread data available in the underlying stream
// since the base class will not handle an empty file.
// Read a byte to see if there is data and if so,
// push it back onto the stream...
byte[] b=new byte[1];
int ret=in.read(b,0,1);
if (ret==-1)
{
eos=true;
return -1;
}
else
((PushbackInputStream)this.in).unread(b, 0, 1);
}

MultiMemberGZIPInputStream child;
if (this.size==-1)
child=new MultiMemberGZIPInputStream(this);
else
child=new MultiMemberGZIPInputStream(this, this.size);
return child.read(inputBuffer, inputBufferOffset, inputBufferLen);
}
else
return charsRead;
}

}
xql80329 2009-01-09
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 java2000_net 的回复:]
gzin.read(

这个一定被重写了。

解压缩你参考这个看看!
http://www.java2000.net/p7764
http://www.java2000.net/p12172
[/Quote]
ZIP跟GZ处理方法不太一样

dashi99 2009-01-09
  • 打赏
  • 举报
回复
应该是绝对路径吧
老紫竹 2009-01-09
  • 打赏
  • 举报
回复
gzin.read(

这个一定被重写了。

解压缩你参考这个看看!
http://www.java2000.net/p7764
http://www.java2000.net/p12172
xql80329 2009-01-08
  • 打赏
  • 举报
回复
args[0]="aaaa.gz";
这行就是红色部分
socool627 2009-01-08
  • 打赏
  • 举报
回复
帮顶
pailman 2009-01-08
  • 打赏
  • 举报
回复
mark
xql80329 2009-01-08
  • 打赏
  • 举报
回复
不继续往下执行比较郁闷

怎么没人回答?????
xql80329 2009-01-08
  • 打赏
  • 举报
回复
没有异常
gzin.read(buf,0,buf.length) 这个打印出来是 478


手工解压后 原文件部分内容
.....
#Remark: 0108066005 "172.17.17.245 - Blue Coat SG210 Series" "172.17.17.245" "main"
2008-11-05 01:54:03 264 10.10.142.158 - - - PROXIED "none" ............

就是到了main 不执行

pxcong007 2009-01-08
  • 打赏
  • 举报
回复
把你代码重新捋了一遍, 贴上来, 请参考, 不知对你是否有用。



package com.question;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/**
* GZIPInputStream question.
*
* @date 2008-1-8
* @author Xxx
*/
public class Q2 {

// GZ file name : eg. C:\\demo.gz
private static final String GZ_FILE_NAME = "C:\\demo.gz";

// the string will be writed in the file
private static final String TEST_STRING = "Test .Test .Test .Test .Test .Test .Test .";

// this String is used for naming the gz file
private static final String FROM_FILE_NAME = "C:\\demo.gz";

// this String is used for naming the log file(according to the user's need, you can modify it.).
private static final String TO_FILE_NAME = "c:\\app.log";

/**
* this method only for init a gz file.
* if you hava a gz file, need not invode it.
* Note: the generated file is stored "C:\\demo.gz"
*/
@Deprecated
public void writeFile() {
try {
StringBuilder sb = new StringBuilder(TEST_STRING);

/*
* populate String
*/
for (int i = 0; i < 15; i ++) {
sb.append(sb);
}
String output = sb.toString();

File file = new File(GZ_FILE_NAME);
if (!file.exists()) {
file.createNewFile();
}
BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(file));
GZIPOutputStream out = new GZIPOutputStream(outputStream);
out.write(output.getBytes());

// TODO only for test. so close in this place.
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

/**
*
* Main method.
*
* @param args
*/
public static void main(String[] args) {
try {
/*
* init file . get a gz file.
*/
// TODO
// Q2 q2 = new Q2();
// q2.writeFile();

/*
* create file
*/
File inputFile = new File(FROM_FILE_NAME);
if (!inputFile.exists()) {
inputFile.createNewFile();
}
FileInputStream inputStream = new FileInputStream(inputFile);
GZIPInputStream gzip = new GZIPInputStream(inputStream);

/*
* create file
*/
File outputFile = new File(TO_FILE_NAME);
if (!outputFile.exists()) {
outputFile.createNewFile();
}

FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream);

/*
* write file
*/
int b;
while((b = gzip.read()) != -1) {
bos.write(b);
}

// only for test, should be close in a correct way(eg. finally ).
gzip.close();
bos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
pxcong007 2009-01-08
  • 打赏
  • 举报
回复
具体异常发上来,
xql80329 2009-01-08
  • 打赏
  • 举报
回复
25M的 压缩包 解压后差不多200M

现在写入文件只能写入1K的数据
后面的大部分数据写不进去
不知道为什么
Alien 2009-01-08
  • 打赏
  • 举报
回复
帮顶~~~关注中~
xql80329 2009-01-08
  • 打赏
  • 举报
回复
现在就是 要用程序解压

找到原因了 是因为没有完全解压了
只解压出一部分 所以就读出十几行


解压的时候还需要怎么控制呢?
pxcong007 2009-01-08
  • 打赏
  • 举报
回复
如果你用的是Eclipse , 你也可以在Run Configuration里

Arguments选项卡里

将Program arguments 参数设置为 c:/aaaa.gz , 即可运行。

pxcong007 2009-01-08
  • 打赏
  • 举报
回复


因为你的String[] args 没有初始话, 所以会抛数组越界错误(Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0)。

修改成这样试试,


package com.question;

import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.GZIPInputStream;

public class Q2 {

public static void main(String[] args) {
args = new String[1];
args[0] = "c:/aaaa.gz";
try {

if (args.length == 0) {
System.out.println("usage: java expandgz filename.gzzzzzzzzzz");
System.exit(0);
}
GZIPInputStream gzi = new GZIPInputStream(new FileInputStream(args[0]));
int to = args[0].lastIndexOf('.');
if (to == -1) {
System.out.println("usage: java expandgz filename.gz");
System.exit(0);
}
String fout = args[0].substring(0, to);

BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(fout));
System.out.println("writing " + fout);
int b;
do {
b = gzi.read();
if (b == -1)
break;
bos.write(b);
} while (true);
gzi.close();
bos.close();

} catch (Exception e) {
e.printStackTrace();

}
}
}
xql80329 2009-01-08
  • 打赏
  • 举报
回复
 public static void main(String[] args)  {

try
{
int nnumber;
FileInputStream fin=new FileInputStream("c:\\abc\\SG_main__2451110060000.log.done.gz"); GZIPInputStream gzin=new GZIPInputStream(fin);
FileOutputStream fout=new FileOutputStream("c:\\abc\\cc.log");
byte[] buf=new byte[1024];

while ((nnumber=gzin.read(buf,0,buf.length)) != -1)
fout.write(buf,0,nnumber);


gzin.close();
fout.close();
fin.close();
}
catch(IOException e)
{
System.out.println(e);
}

}
}

我修改成上面这样 可以读但是只读前面十几行就不往下读了!为什么呢?
byte[] buf=new byte[1024]; 调它的大小也没有变化!

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧