java(android): 尝试压缩 I/O 并失败

发布于 2024-11-06 19:25:05 字数 1603 浏览 3 评论 0原文

基本上我有一个相当长的文本,我需要将其压缩,将其存储在文件中,并稍后读出。这就是我所做的。

public static void outCompressNIO(String outFile, String src) {
    FileChannel fc = null;
    GZIPOutputStream gz = null;
    try {
        fc = new FileOutputStream(outFile).getChannel();
        gz = new GZIPOutputStream(Channels.newOutputStream(fc));
        gz.write(src.getBytes());
        gz.flush();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            gz.close();
            fc.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

public static void inCompressNIO(String inFile) {
    FileChannel fc = null;
    GZIPInputStream gz = null;
    try {
        fc = new FileInputStream(inFile).getChannel();
        gz = new GZIPInputStream(Channels.newInputStream(fc));
        byte fileContent[] = new byte[1024];
        StringBuilder sb = new StringBuilder();
        while ((gz.read(fileContent)) != -1) {
            sb.append(new String(fileContent));
        }
        System.out.println(sb.toString());
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            gz.close();
            fc.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

但是我从压缩文件中返回的字符串与原始的字符串各地都不同。有人知道为什么吗?顺便说一句,我的主要目标是我需要有效地将一个长字符串(大约15M)压缩到一个文件中,并将其解压缩到android上的主内存中。我尝试在java中使用Object IO来实现这一点,在我的电脑上实现没有问题。但在android上,如果字符串对象超过3M,则需要很长时间才能将我从ObjectInputStream获得的对象转换为String。所以我正在尝试其他方法来避免铸造。以上是我的尝试之一,但由于我对 NIO 知之甚少,我可能做错了,所以任何人都知道更有效的方法来实现这一点,请为我指出正确的方向,非常感谢。

Basically I have a text that is quite long, I need to compress it, store it in a file, and read it out later. here is what I did.

public static void outCompressNIO(String outFile, String src) {
    FileChannel fc = null;
    GZIPOutputStream gz = null;
    try {
        fc = new FileOutputStream(outFile).getChannel();
        gz = new GZIPOutputStream(Channels.newOutputStream(fc));
        gz.write(src.getBytes());
        gz.flush();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            gz.close();
            fc.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

public static void inCompressNIO(String inFile) {
    FileChannel fc = null;
    GZIPInputStream gz = null;
    try {
        fc = new FileInputStream(inFile).getChannel();
        gz = new GZIPInputStream(Channels.newInputStream(fc));
        byte fileContent[] = new byte[1024];
        StringBuilder sb = new StringBuilder();
        while ((gz.read(fileContent)) != -1) {
            sb.append(new String(fileContent));
        }
        System.out.println(sb.toString());
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            gz.close();
            fc.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

But the string I got back from the compressed file is different with the original one from place to place. Anyone knows why? By the way, my main goal is that I need to effectively compress a long string(around 15M) into a file, and decompress it into main memory on android. I tried to just use Object IO in java to achieve this, it is achieved with no problem on my pc. But on android, if the string object is more than 3M, it takes forever to cast the object I got from ObjectInputStream to String. So I am trying other ways to avoid casting. The above is one of my attempts, but since I know little about NIO, I am probably doing it all wrong, so anyone knows a more efficient way to achieve this, please point me to the right direction, Thanks a lot.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

鸩远一方 2024-11-13 19:25:05
  1. 扔掉FileChannel,只使用FileInputStream。你在这里实际上使用的是 java.io,而不是 NIO,除非你获得通道,所以你只是在以困难的方式做这件事。
  2. 为 String.getBytes() 指定字符集名称。
  3. 将 read(byte[]) 的结果存储到变量中。
    追加到 sb 时使用该变量,即 sb.append(new String(buffer,0,count, charset));
  4. 更好的是,在 GZipInputStream 周围包装一个 InputStreamReader,使用相同的字符集名称构造,读入 char[] 数组,而不是 byte[] 数组,并使用 sb.append(charBuffer, 0, count)。这避免了您当前所读取的字节构成整个字符串的假设。
  1. Throw away the FileChannel and just use FileInputStream. You're using java.io here really, not NIO, except when you get the channel, so you're just doing it the hard way.
  2. Specify a charset name to String.getBytes().
  3. Store the result of read(byte[]) into a variable.
    Use that variable when appending to sb, i.e. sb.append(new String(buffer,0,count, charset));
  4. Better still, wrap an InputStreamReader around the GZipInputStream, constructed with the same charset name, read into a char[] array, not a byte[] array, and use sb.append(charBuffer, 0, count). This avoids the assumption you're presently making that the bytes you read constitute an entire String.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文