欢迎光临
我们一直在努力

调整JavaTM 的I/O性能(三)(zt)-JSP教程,Java技巧及代码

建站超值云服务器,限时71元/月

压缩

java提供了对字节流进行压缩和解压缩的类。它们可以在java.util.zip包中被找到,同时也作为jar文件的基 础(jar文件是具有一个清单的zip文件)。

以下的程序采用一个单一的输入文件,并且生成一个压缩了的zip输出文件,该程序带有一个表示输入文件的 入口项。

      import java.io.*;

      import java.util.zip.*;

      public class compress {

          public static void doit(string filein, string fileout) {

              fileinputstream fis = null;

              fileoutputstream fos = null;

              try {

                  fis = new fileinputstream(filein);

                  fos = new fileoutputstream(fileout);

                  zipoutputstream zos = new zipoutputstream(fos);

                  zipentry ze = new zipentry(filein);

                  zos.putnextentry(ze);

                  final int bufsiz = 4096;

                  byte inbuf[] = new byte[bufsiz];

                  int n;

                  while ((n = fis.read(inbuf)) != -1)

                      zos.write(inbuf, 0, n);

                  fis.close();

                  fis = null;

                  zos.close();

                  fos = null;

              }

              catch (ioexception e) {

                  system.err.println(e);

              }

              finally {

                  try {

                      if (fis != null)

                          fis.close();

                      if (fos != null)

                          fos.close();

                  }

                  catch (ioexception e) {

                  }

              }

          }

          public static void main(string args[]) {

              if (args.length != 2) {

                  system.err.println("missing filenames");

                  system.exit(1);

              }

              if (args[0].equals(args[1])) {

                  system.err.println("filenames are identical");

                  system.exit(1);

              }

              doit(args[0], args[1]);

          }

      }

下一个程序正好相反,采用假定只有一个入口项的zip输入文件,并且将该项解压到指定的输出文件:

      import java.io.*;

      import java.util.zip.*;

      public class uncompress {

          public static void doit(string filein, string fileout) {

              fileinputstream fis = null;

              fileoutputstream fos = null;

              try {

                  fis = new fileinputstream(filein);

                  fos = new fileoutputstream(fileout);

                  zipinputstream zis = new zipinputstream(fis);

                  zipentry ze = zis.getnextentry();

                  final int bufsiz = 4096;

                  byte inbuf[] = new byte[bufsiz];

                  int n;

                  while ((n = zis.read(inbuf, 0, bufsiz)) != -1)

                      fos.write(inbuf, 0, n);

                  zis.close();

                  fis = null;

                  fos.close();

                  fos = null;

              }

              catch (ioexception e) {

                  system.err.println(e);

              }

              finally {

                  try {

                      if (fis != null)

                          fis.close();

                      if (fos != null)

                          fos.close();

                  }

                  catch (ioexception e) {

                  }

              }

          }

          public static void main(string args[]) {

              if (args.length != 2) {

                  system.err.println("missing filenames");

                  system.exit(1);

              }

              if (args[0].equals(args[1])) {

                  system.err.println("filenames are identical");

                  system.exit(1);

              }

              doit(args[0], args[1]);

          }

      }

压缩是有助还是损害i/o性能很大程度上依赖于本地硬件设置;尤其是处理器和磁盘驱动器的相对速度。采用 zip技术进行压缩,典型地将数据量减少50%,但是有一些压缩和解压的时间开销。在带ide磁盘驱动器的 300-mhz pentium pc上,对一个大的压缩文本文件(5-10mb)的实验表明,从磁盘读取压缩文件比非压缩文件 快将近1/3。

充分展现压缩优越性的一个例子是在写入象软盘这样的低速介质。使用高速处理器 (300 mhz pentium)和低 速软盘(pc上常用的软盘驱动器)进行的测试显示,压缩一个大文本文件,然后写入软盘,比直接将文件拷 贝到软盘快50%。

高速缓存

关于硬件的高速缓存的详细讨论超出了本文的范围。但是,有时软件高速缓存 能够加速i/o。考虑这样一个 例子,需要以随机的方式读取文本文件的某些行。完成的方法之一是读入所有的行,并且把它们存储在 arraylist(一个与vector相似的collection类)中:

      import java.io.*;

      import java.util.arraylist;

      public class linecache {

          private arraylist list = new arraylist();

          public linecache(string fn) throws ioexception {

              filereader fr = new filereader(fn);

              bufferedreader br = new bufferedreader(fr);

              string ln;

              while ((ln = br.readline()) != null)

                  list.add(ln);

              br.close();

          }

          public string getline(int n) {

              if (n < 0)

                  throw new illegalargumentexception();

              return (n < list.size() ?

                  (string)list.get(n) : null);

          }

          public static void main(string args[]) {

              if (args.length != 1) {

                  system.err.println("missing filename");

                  system.exit(1);

              }

              try {

                  linecache lc = new linecache(args[0]);

                  int i = 0;

                  string ln;

                  while ((ln = lc.getline(i++)) != null)

                      system.out.println(ln);

              }

              catch (ioexception e) {

                  system.err.println(e);

              }

          }

      }

getline方法被用来检索任意的一行。这项技术非常有用,但对于大文件而言,显然需要使用了大量的内存, 因此具有局限性。一个替代方法是仅仅记住最近被请求的100行,必要时从磁盘上读取其他行。在存在行的存 储局部性这种情况下,这个方案运行良好,但是需要真正的随机存储时就没有这么好了。

标志化(tokenization)

标志化(tokenization)指将字节或者字符序列拆散成象词一样的逻辑块的过程。java提供了streamtokenizer 类,可以进行如下的操作:

      import java.io.*;

      public class token1 {

          public static void main(string args[]) {

              if (args.length != 1) {

                  system.err.println("missing filename");

                  system.exit(1);

              }

              try {

                  filereader fr = new filereader(args[0]);

                  bufferedreader br = new bufferedreader(fr);

                  streamtokenizer st = new streamtokenizer(br);

                  st.resetsyntax();

                  st.wordchars(a, z);

                  int tok;

                  while ((tok = st.nexttoken()) !=

                              streamtokenizer.tt_eof) {

                      if (tok == streamtokenizer.tt_word)

                          ; // st.sval has token

                  }

                  br.close();

              }

              catch (ioexception e) {

                  system.err.println(e);

              }

          }

      }

本例根据小写字母(字母a-z)进行标记。如果由您自己实现了其等效程序,可能看上去象这样:

      import java.io.*;

      public class token2 {

          public static void main(string args[]) {

              if (args.length != 1) {

                  system.err.println("missing filename");

                  system.exit(1);

              }

              try {

                  filereader fr = new filereader(args[0]);

                  bufferedreader br = new bufferedreader(fr);

                  int maxlen = 256;

                  int currlen = 0;

                  char wordbuf[] = new char[maxlen];

                  int c;

                  do {

                      c = br.read();

                      if (c >= a && c <= z) {

                          if (currlen == maxlen) {

                              maxlen *= 1.5;

                              char xbuf[] =

                                  new char[maxlen];

                              system.arraycopy( wordbuf, 0,

                                              xbuf, 0, currlen);

                              wordbuf = xbuf;

                          }

                          wordbuf[currlen++] = (char)c;

                      }

                      else

                          if (currlen > 0) {

                              string s = new string(wordbuf, 0,

                                              currlen);

                              // do something with s

                              currlen = 0;

                          }

                  } while (c != -1);

                  br.close();

              }

              catch (ioexception e) {

                  system.err.println(e);

              }

          }

      }

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » 调整JavaTM 的I/O性能(三)(zt)-JSP教程,Java技巧及代码
分享到: 更多 (0)