二进制文件中的Java移位字符

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二进制文件中的Java移位字符相关的知识,希望对你有一定的参考价值。

我查看了一些关于二进制文件的先前线程,我正在按照它说的做DataStream,但我不确定为什么我的工作不正常,因为我认为我做的事与线程说我一样。我的目标是创建一个方法,该文件名采用.bin格式的文件名和移位整数。我将创建一个.bin类型的新文件,其中字符已移位。只会移动大写字母或小写字母。我不知道正在读入的二进制文件的长度,需要遍历所有字符。该文件只有1行。我有一个方法,它给我该行上的字符数和一个创建文件的方法。我知道的程序确实正确地创建了文件。无论如何,正在发生的是它创建文件,然后给我一个关于该行的EOF异常:char currentChar = data.readChar();

这是我的代码:

private static void cipherShifter(String file, int shift) {
        String newFile=file+"_cipher";
        createFile(newFile);
        int numChar;
        try {
            FileInputStream stream=new FileInputStream(file);
            DataInputStream data=new DataInputStream(stream);

            FileOutputStream streamOut=new FileOutputStream(newFile);
            DataOutputStream dataOut=new DataOutputStream(streamOut);
            numChar=readAllInts(data);
            for (int i=0;i<numChar;++i) {
                char currentChar=data.readChar();
                if (((currentChar>='A')&&(currentChar<='Z'))||((currentChar>='a')&&(currentChar<='z'))) {
                    currentChar=currentChar+=shift;
                    dataOut.writeChar(currentChar);
                }
                else {
                    dataOut.writeChar(currentChar);
                }

            }
            data.close();
            dataOut.flush();
            dataOut.close();
        } catch(IOException error) {
            error.printStackTrace();
        }
    }

    private static void createFile(String fileName) {
        File file=new File(fileName);
        if (file.exists()) {
            //Do nothing
        }

        else {
            try {
                file.createNewFile();
            } catch (IOException e) {
                //Do nothing
            }
        }
    }

    private static int readAllInts(DataInputStream din) throws IOException {
        int count = 0; 
        while (true) { 
            try { 
                din.readInt(); ++count; 
            } catch (EOFException e) { 
                return count; 
            } 
        }
    }

所以我认为不应该发生错误,因为我确实有正确的数据类型,我告诉它只读一个字符。任何帮助都会很棒。提前致谢。

答案

根据上面的描述,您的错误将在data.readChar()方法调用中报告,而不是在readAllInts方法中报告。我模拟了错误附近的代码,并在同一位置的文本文件中获得了相同的异常。

我使用readByte方法一次读取一个字节,因为您主要对ASCII字节感兴趣。我还将readAllInts更改为readAllBytes,因此我使用总字节数。

private static void cipherShifter(String file, int shift) {
        String newFile=file+"_cipher";
        createFile(newFile);
        int numChar;
        try {
            FileInputStream stream=new FileInputStream(file);
            DataInputStream data=new DataInputStream(stream);

            FileOutputStream streamOut=new FileOutputStream(newFile);
            DataOutputStream dataOut=new DataOutputStream(streamOut);
            numBytes=readAllBytes(data);
            stream.close();
            data.close();
            stream=new FileInputStream(file);
            data=new DataInputStream(stream);
            for (int i=0;i<numBytes;++i) {
                byte currentByte=data.readByte();
                if (((currentByte>=65)&&(currentByte<=90))||((currentByte>=97)&&(currentByte<=122))) {
                    currentByte=currentByte+=shift; //need to ensure no overflow beyond a byte
                    dataOut.writeByte(currentByte);
                }
                else {
                    dataOut.writeByte(currentByte);
                }

            }
            data.close();
            dataOut.flush();
            dataOut.close();
        } catch(IOException error) {
            error.printStackTrace();
        }
    }

    private static void createFile(String fileName) {
        File file=new File(fileName);
        if (file.exists()) {
            //Do nothing
        }

        else {
            try {
                file.createNewFile();
            } catch (IOException e) {
                //Do nothing
            }
        }
    }

    private static int readAllBytes(DataInputStream din) throws IOException {
        int count = 0; 
        while (true) { 
            try { 
                din.readByte(); ++count; 
            } catch (EOFException e) { 
                return count; 
            } 
        }
    }
另一答案

看起来你正在获得EOFException,因为你将DataInputStream对象传递给readAllInts方法,读取流,然后尝试在for循环中再次读取它。问题在于,当readAllInts返回时,跟踪您在流中的位置的指针已经接近流的末尾(或在流的末尾)。我怀疑它接近结束,而不是它,因为readChar()方法立即抛出EOFException,当它只读取它希望能够在击中EOF之前读取的两个字节之一时它会这样做。

要解决这个问题,可以在将reader传递给readAllInts方法之前调用data.mark(),然后在该方法返回后调用data.reset();这会将指针重新指向流的开头。 (这假设data.markSupported()为true。)

你也遇到了我们上面谈到的问题,你的计数器一次读取四个字节,你的字符阅读器一次读两个字节。你建议的将readAllInts的返回值加倍的方法会有所帮助(你也可以使用readChar()而不是readInt()。)

您仍然需要考虑如何处理奇数字节长的二进制文件的情况。您可以通过多种方式处理该问题。我今晚也打得写代码样本,但如果你明天仍然被卡住,请添加评论,我会看到我能做些什么来帮助你。

以上是关于二进制文件中的Java移位字符的主要内容,如果未能解决你的问题,请参考以下文章

java 移位运算

韩顺平 java笔记 第20讲 二进制 位运算 移位运算

如何将两个每个 8 位的数组(二进制数字字符串组合成一个 16 位的单个字符串?(arduino,移位寄存器)

java中的移位问题 程序如下

java的移位和异或运算

Java中处理二进制移位