从文件输入流中读取时,为什么必须将字节转换为字节?

时间:2015-07-05 07:04:21

标签: java file-io casting

我目前正在通过在线java课程学习,主题是关于使用输入流进行读写。具体来说,本课程演示了如何使用用户输入的加班来加密图像文件,然后使用负移位解密同一图像文件。

然而,在提供的代码中,我不明白关键线实际上做了什么,以及它为什么做它做的事情。从我可以做到的,它从FileInputStream读取一个字节并将其转换为一个字节,然后在通过文件输出流写出之前将移位添加到它。但是,由于我已经从FileInputStream读取了一个字节,为什么我必须将它再次强制转换为一个字节?

我真的很感激有人对此有所了解。

谢谢!

import java.io.*;
import java.util.Scanner;

public class ReadingAndWritingStreamsNonText {
    public static String imgFilePath = "C:\\JavaProjects\\BinaryStreams\\src\\MIM_BINARY_MEME.jpg";
    public static String imgFilePath2 = "C:\\JavaProjects\\BinaryStreams\\src\\data.bin";
    public static String imgFilePath3 = "C:\\JavaProjects\\BinaryStreams\\src\\MIM_BINARY_MEME_Decrypted.jpg";

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("Please enter a shift to encrypt/decrypt the file:");
        int shift = Integer.parseInt(input.nextLine());

        try {
            FileInputStream fis = null;
            FileOutputStream fos = null;
            PrintStream ps = null;

            if (shift > 0) {
                fis = new FileInputStream(imgFilePath);
                fos = new FileOutputStream(imgFilePath2);
                ps = new PrintStream(fos);
            }
            else {
                fis = new FileInputStream(imgFilePath2);
                fos = new FileOutputStream(imgFilePath3);
                ps = new PrintStream(fos);
            }

            boolean done = false;
            while (!done) {
                //read in the file
                int next = fis.read();
                if (next == -1) {
                    done = true;
                }
                else {
                    //encrypt or decrypt based on shift
                    **ps.write(((byte) next) + shift);** <--- this line
                }
            }

            ps.close();
            ps = null;
            fos.close();
            fos = null;
            fis.close();
            fis = null;
        }
        catch (IOException ioex) {
            ioex.printStackTrace();
        }
        System.out.println("Operation Completed");
    }
}

3 个答案:

答案 0 :(得分:4)

因为InputStream.read()会返回int而不是byte

请注意,此方法将在到达流末尾时返回-1,如果读取了一个字节,则返回0到255之间的值,如API文档所示:

  

从输入流中读取下一个数据字节。值字节作为int返回,范围为0到255.如果没有字节可用,因为已到达流的末尾,则返回值-1。此方法将阻塞,直到输入数据可用,检测到流的末尾或抛出异常。

int需要转换为byte,因为int是32位,而一个字节只有8位。你不能进行缩小转换(抛弃int的高24位)而不进行强制转换。

答案 1 :(得分:4)

  

它从fileinputstream读取一个字节并将其强制转换为一个字节,然后在通过文件输出流写出之前将移位添加到它。但是,由于我已经从fileinputstream读取一个字节,为什么我必须再次将它转换为一个字节?

因为read()返回int,可能是-1,表示流的结束。如果它不是-1,则它是0..255范围内的值,您必须将其byte强制转换为byte,范围为-128..127 。如果没有遵循此流程,则无法通过返回值指示流的结束。

答案 2 :(得分:2)

FileInputStream.read()返回一个int,而不是byte,因为:Why does InputStream#read() return an int and not a byte?

但是你想要准确地移位8位数据,并且int更大(32位)。所以你需要把它转换成字节。