Java FileOutputStream写入负字节值,写入错误字节

我遇到了一个问题,使用FileOutputStream将负字节值写入二进制文件,其中负字节值,例如。 -1被写入文件,但它占用了两个字节,在我看来,它们完全是胡说八道。

在我的应用程序中,某些对象具有toByteArray()返回byte [],因此可以将其写入文件。即使它在许多对象上都“有效”,我还是将对象序列化为存在一些负字节的字节数组(新的byte [] {0,0,0,1,-1,-1,-1,-1, 1,3,-48,-5,10}),当我将该对象写入文件时,负数将被写为“ c0 a2”字节。

测试用例:

public void testWRITE() {
    String fileName = "TEST_FILE.lldb";
    String secondFileName = "SECOND_FILE.lldb";
    FileOutputStream fos;
    FileOutputStream fos2;
    try {
        fos = new FileOutputStream(fileName,false);
        fos2 = new FileOutputStream(secondFileName,false);

        // Writing this to file writes bytes "c2 a0" in place of -1 byte
        FileChannel ch = fos.getchannel();
        ch.position(0);
        ch.write(ByteBuffer.wrap(new byte[] {0,1,-1,3,-48,-5,10}));


        // Writing this to file writes "ff" in of -1 byte
        Pojo pojo = new Pojo();
        FileChannel ch2 = fos2.getchannel();
        ch2.position(0);
        ch2.write(ByteBuffer.wrap(pojo.getBytes()));

        fos.close();
        fos2.close();

    } catch (IOException e) {
        fail();
    }
}

其中Pojo类是简单的POJO,

public class Pojo {

    private Integer negativeNumber;

    public Pojo() {
        this.negativeNumber = -1;
    }

    public byte[] getBytes() {
        return Pojo.bytesFromInt(this.negativeNumber);
    }

    public static byte[] bytesFromInt(int value) {
         return new byte[] {
            (byte)(value >>> 24),(byte)(value >>> 16),(byte)(value >>> 8),(byte)value};
    }}

我指望着这样一个事实,当我向文件中写入一个字节将只是一个字节时,由于它是我图书馆的基石,因此我无法继续进行工作。

错误的字节数而不是负数

Java FileOutputStream写入负字节值,写入错误字节

用负整数写序列化的POJO转换为字节数组

Java FileOutputStream写入负字节值,写入错误字节

这是否甚至被视为FileOutputStream的预期行为? 我想念什么?

gaoy969 回答:Java FileOutputStream写入负字节值,写入错误字节

一切都写正确。

写负数时,它们以二进制补码形式书写。

因此,写-5 = 1111 1011(十六进制为FB)。这就是您所看到的。

并且FF = 1111 1111 = -1

这是我用来检查结果的修改后的代码。请注意,我在文件名中添加了逻辑文件字母。也许我做错了。

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Arrays;

public class Writing {
   public static void main(String[] args) {
      testWRITE();

   }

   public static void testWRITE() {
      String fileName = "F:/TEST_FILE.lldb";
      String secondFileName = "F:/SECOND_FILE.lldb";
      FileOutputStream fos;
      FileOutputStream fos2;
      try {
         fos = new FileOutputStream(fileName,false);
         fos2 = new FileOutputStream(secondFileName,false);

         // Writing this to file writes bytes "0c2 a0" in place of -1 byte
         FileChannel ch = fos.getChannel();
         ch.position(0);
         System.out.println("Writing to " + fileName);
         ByteBuffer b = ByteBuffer.wrap(
               new byte[] { 0,1,-1,3,-48,-5,10
               });

         System.out.println(Arrays.toString(b.array()));
         ch.write(b);
         // Writing this to file writes "ff" in of -1 byte
         Pojo pojo = new Pojo();
         FileChannel ch2 = fos2.getChannel();
         ch2.position(0);
         System.out.println("Writing to " + secondFileName);
         ch2.write(ByteBuffer.wrap(pojo.getBytes()));
         System.out.println(Arrays.toString(pojo.getBytes()));

         fos.close();
         fos2.close();

         System.out.println();
         FileInputStream fs = new FileInputStream(fileName);
         FileInputStream fs2 = new FileInputStream(secondFileName);
         System.out.println("Reading all bytes from " + fileName);
         byte[] bs = fs.readAllBytes();
         System.out.println(Arrays.toString(bs));
         System.out.println("Reading all bytes from " + secondFileName);
         bs = fs2.readAllBytes();
         System.out.println(Arrays.toString(bs));
      }
      catch (IOException e) {
         System.out.println(e.getMessage());
      }
   }
}

class Pojo {

   private Integer negativeNumber;

   public Pojo() {
      this.negativeNumber = -1;
   }

   public byte[] getBytes() {
      return Pojo.bytesFromInt(this.negativeNumber);
   }

   public static byte[] bytesFromInt(int value) {
      return new byte[] {
            (byte) (value >>> 24),(byte) (value >>> 16),(byte) (value >>> 8),(byte) value
      };
   }
}

这是我的输出。

Writing to F:/TEST_FILE.lldb
[0,10]
Writing to F:/SECOND_FILE.lldb
[-1,-1]

Reading all bytes from F:/TEST_FILE.lldb
[0,10]
Reading all bytes from F:/SECOND_FILE.lldb
[-1,-1]

,

这有点尴尬,因为我不仅是初学者,而且是的,我错了。当我将该文件读回内存时,实际上只是我以前写入文件中的那些字节。但是为了支持我的职位和态度,我并没有真正运行仅发布的任何其他代码。但是,使用带有HEXEditor扩展名的Notepad ++来查看该文件确实显示了“ FF”和“ C2 A0”,即使我将文件读回内存时字节也只是“字节”,但是我却看到“ C2”,我不知道为什么文件中的“ A0”,我什至没有想到将其读回内存以进行检查。 CaptainObvious提到“在某处”执行UTF-8转换,但是如果是这样,那不在我的代码中。

本文链接:https://www.f2er.com/2973677.html

大家都在问