java - FileInputStream 在skip()调用后留下奇怪的垃圾文本

标签 java android inputstream fileinputstream fileoutputstream

需求:

我也想将数据写入压缩格式和普通格式。当我必须将数据写入压缩格式时,“useCompression”将作为“true”发送,而当数据需要以正常格式(因为它被提供给 Writer 类)存储时,“useCompression”将为 false。

这里的问题是,当Reader类尝试读取数据时,如何判断数据是否被压缩? 因此,为了解决这个问题,如果“useCompression”为真,我将“1”写入文件,如果“useCompression”为假,则将“0”写入文件。

编写没问题,但是当我们尝试使用“fIn.skip(1)”跳过第一个元素(因为它是标识符而不是实际数据)时,它会留下一些垃圾值。

例如,我试图将“2019-07-31”写入文件,而“useCompression”为 false,因此我的文件将保存“02019-07-31”并发布“fIn.skip(1)” ” 称它应该包含“2019-07-31”,但它包含“^@2019-07-31”。

请帮我弄清楚我在这里做错了什么

我尝试将 Reader 类的构造函数更新为:

    public Reader(String key)
    {
        mKey = key;
        try {
            FileInputStream fIn = new FileInputStream(streamFileForKey(key));
            byte[] firstByte = new byte[1];
            int read = fIn.read(firstByte);
            boolean shouldUseDecompression = (1 == firstByte[0]);

            if (shouldUseDecompression) {
                mFin = new GZIPInputStream(fIn);
            }
            else {
                mFin = fIn;
            }
        }
        catch (Exception e) {
            System.out.println("Failed to open (r) key " + key + " exception : " + e);
        }
    }   

但这并不能解决问题。

实际代码是:

import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import java.io.DataOutputStream;

import java.util.zip.GZIPOutputStream;
import java.util.zip.GZIPInputStream;

public class forStackOverflow {
    public static void main(String []args) {
        // Write to normal file
        mReader1 = new Reader(mInputFileName);
        mWriter1 = new Writer(mOutputFilename1, false);
        int availableBytes = mReader1.availableBytes();
        int readBytes = 1000;
        while (availableBytes > 0)
        {
            if (availableBytes >= 1000) {
                availableBytes = availableBytes - readBytes;
            }
            else {
                readBytes = availableBytes;
                availableBytes = availableBytes - readBytes;
            }

            mWriter1.write(mReader1.read(readBytes), 0, readBytes);
        }
        mReader1.close();
        mWriter1.close();
    }

    private static File streamFileForKey(String key)
    {
        return new File(key);
    }

    static String mInputFileName = "~/Downloads/inputStream.txt";
    static String mOutputFilename1 = "~/Downloads/outputStream.txt";

    static Reader mReader1;

    static Writer mWriter1;

    private static class Writer
    {
        public Writer(String key, boolean useCompression) {
            mKey = key;

            try {
                FileOutputStream fileOutput = new FileOutputStream(streamFileForKey(key));
                if (useCompression) {
                    fileOutput.write(1);
                    gOutputStream = new GZIPOutputStream(fileOutput);
                }
                else {
                    fileOutput.write(0);
                    gOutputStream = new DataOutputStream(fileOutput);
                }
            }
            catch (Exception e) {
                System.out.println("Got error while opening stream for " + mKey + ". Ex: " + e);
            }
        }

        public boolean write(byte[] bytes, int pos, int len)
        {
            boolean retVal = true;

            if (gOutputStream == null) {
                return false;
            }

            try {
                gOutputStream.write(bytes, pos, len);
                retVal = true;
            }
            catch (Exception e) {
                System.out.println("Failed to write " + len + " bytes to key " +
                        mKey + e);
                retVal = false;
            }

            return retVal;
        }

        public void close()
        {
            if (gOutputStream != null) {
                try {
                    gOutputStream.close();
                }
                catch (Exception e) {
                    System.out.println("Failed to close key " + mKey + e);
                }
                gOutputStream = null;
            }
        }

        private String mKey;
        private OutputStream gOutputStream;
    }

    private static class Reader
    {
        public Reader(String key)
        {
            mKey = key;
            try {
                FileInputStream fIn = new FileInputStream(streamFileForKey(key));

                if (shouldUseDecompression()) {
                    long skipped = fIn.skip(1);
                    mFin = new GZIPInputStream(fIn);
                }
                else {
                    long skipped = fIn.skip(1);
                    mFin = fIn;
                }
            }
            catch (Exception e) {
                System.out.println("Failed to open (r) key " + key + " exception : " + e);
            }
        }

        public byte[] read(int len)
        {
            if (mFin == null) {
                return null;
            }

            byte[] b = null;
            try {
                b = new byte[len];
                int read;
                read = mFin.read(b, 0, len);
                if (read <= 0) {
                    return null;
                }
            }
            catch (Exception e) {
                System.out.println("Failed to read " + len + " bytes from key " +
                        mKey + " exception : " + e);
            }

            return b;
        }

        public void close()
        {
            if (mFin != null) {
                try {
                    mFin.close();
                }
                catch (Exception e) {
                    System.out.println("Failed to close key " + mKey + " exception : " + e);
                }
                mFin = null;
            }
        }

        private boolean shouldUseDecompression()
        {
            boolean retVal = false;
            try {
                FileInputStream fIn = new FileInputStream(streamFileForKey(mKey));
                byte[] firstByte = new byte[1];
                int read = fIn.read(firstByte);

                // If first byte is `1` the we need to use decompression on it.
                retVal = (1 == firstByte[0]);
                fIn.close();
            }
            catch(Exception e) {
                System.out.println("Exception in shouldUseDecompression() : " + e);
                retVal = false;
            }

            return retVal;
        }

        public int availableBytes()
        {
            int available = 0;
            try {
                if (mFin != null) {
                    available = mFin.available();
                }
            }
            catch (IOException e) {
                System.out.println("Failed to read available bytes for " + mKey + ". Exception : " + e);
            }

            return available;
        }

        private String mKey;
        private InputStream mFin;
    }
}

预期结果应该是,后“fIn.skip(1)”调用文件应包含“2019-07-31”而不是“^@2019-07-31”。

最佳答案

经过一番挣扎,我发现这正是预期的结果。
^@ 只是我从 Writer 类的构造函数编写的二进制 0,以防 useCompression 为 false。
来自 fileOutput.write(0); 行。

关于java - FileInputStream 在skip()调用后留下奇怪的垃圾文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57858863/

相关文章:

android 套接字连接,inputStream 在 readline 上与 socket.io 或节点 websocket 服务器卡住

java - AudioInput 流无法打开 .wav 文件

java - Java 系统监视器

java - 比较谷歌地图 v2 android 中的两个 LatLng 对象

应用程序内的 android 远程服务与单独的应用程序

android - 不管怎样 告诉 webView 中的内容何时完全加载?

android - onCellLocationChanged 的​​问题

java - 窗口不弹出

java - Powermock 验证非静态方法中的私有(private)静态方法调用

java - 在这种情况下,当我尝试运行单个测试用例脚本时,为什么会打开多个浏览器实例?