【问题标题】:Why is Java/Linux appending 0xa to end of file? [duplicate]为什么 Java/Linux 将 0xa 附加到文件末尾? [复制]
【发布时间】:2014-11-17 19:25:26
【问题描述】:

我正在使用FileOutputStream 编写文件,我注意到十六进制似乎包含终止0x0a。这是文件的输出:

0000000: d100 0b00 0000 4865 6c6c 6f20 776f 726c  ......Hello worl
0000010: 6429 0043 0500 0000 7072 696e 740a       d).C....print.

(Note hex code comes from vim on Osx Yosimite x64)

请注意文件以0x0a 结尾。这是一个 linux 的东西(比如某种 EOF 字符)还是这个 java/FileOutputStream 附加了字符?

编辑:代码

public class FileImageOpcodeRenderer implements OpCodeRenderer, AutoCloseable {
  private final FileOutputStream stream;
  private final Iterable<OpCode> opcodes;
  private final List<Byte> data = new ArrayList<>();

  public FileImageOpcodeRenderer(Iterable<OpCode> opcodes, String path) {
    this.opcodes = opcodes;
    try {
      this.stream = new FileOutputStream(path);
    } catch (IOException ex) {
      ex.printStackTrace();

      throw new CompilerException("Unable to open output file");
    }
  }

  public void save() throws Exception {
    List<Byte> renderedContent = renderOpCodes();
    byte[] content = toArray(renderedContent);
    stream.write(content, 0, content.length);
  }

  private List<Byte> renderOpCodes() {
    for (OpCode opCode : opcodes) {
      writeInt8(null, opCode.opNumber());
      opCode.render(this);
    }

    return this.data;
  }

  private byte[] toArray(List<Byte> data) {
    byte[] content = new byte[data.size()];

    for (int index = 0; index < data.size(); index++) {
      content[index] = data.get(index);
    }

    return content;
  }

  @Override
  public void writeInt8(String label, int value) {
    data.add((byte)value);
  }

  @Override
  public void writeInt16(String label, int value) {
    writeInt8(null, (byte)(value & 0xFF));
    writeInt8(null, (byte)((value >> 8) & 0xFF));
  }

  @Override
  public void writeInt32(String label, int value) {
    writeInt8(null, (byte)(value & 0xFF));
    writeInt8(null, (byte)((value >> 8) & 0xFF));
    writeInt8(null, (byte)((value >> 16) & 0xFF));
    writeInt8(null, (byte)((value >> 24) & 0xFF));
  }

  @Override
  public void writeInt64(String label, long value) {
    writeInt8(null, (byte)(value & 0xFF));
    writeInt8(null, (byte)((value >> 8) & 0xFF));
    writeInt8(null, (byte)((value >> 16) & 0xFF));
    writeInt8(null, (byte)((value >> 24) & 0xFF));
    writeInt8(null, (byte)((value >> 32) & 0xFF));
    writeInt8(null, (byte)((value >> 40) & 0xFF));
    writeInt8(null, (byte)((value >> 48) & 0xFF));
    writeInt8(null, (byte)((value >> 56) & 0xFF));
  }

  @Override
  public void writeString(String label, String value) {
    writeInt32(null, value.length());
    for (byte letter : value.getBytes()) {
      System.out.println((int)letter);
      writeInt8(null, letter);
    }
  }

  @Override
  public void close() throws Exception {
    stream.close();
  }
 }

我什至在查看save 中的原始字节,它以0x74 结尾,而不是0x0a

更新:摩尔代码:

所以我只是写了这段代码来用 c++ 加载文件:

int main() {
    int fd = open("/Users/sircodesalot/Desktop/image.vbaj", O_RDONLY);

    char buffer[256] { };
    int amout = read(fd, buffer, 256);

    cout << amout << endl;

    for (int index = 0; index != 256; ++index) {
        if (index > 0 && (index % 10 == 0)) cout << endl;
        cout << hex << (int)buffer[index] << " ";
    }

    close(fd);
}

输出这个:

29
ffffffd1 0 b 0 0 0 48 65 6c 6c 
6f 20 77 6f 72 6c 64 29 0 43 
5 0 0 0 70 72 69 6e 74 0 
0 0 0 0 0 0 0 0 0 0
... (rest of the 256 byte buffer)

你看,不是0xa吗?这有什么关系?也许是一些 linux 约定?

【问题讨论】:

  • 0x0a 是换行符,Linux 上的行分隔符。你具体写了什么?
  • 是否总是将换行符附加到文件末尾?写“Hello world”的程序和写“print”的程序是一样的,为什么一个有换行符,另一个没有?
  • 换行符不会自动附加到文件中。仅当您使用 println 时才会发生这种情况。
  • 为什么不显示用于编写文件的语句?

标签: java linux


【解决方案1】:

问题可能就在这里:

@Override
public void writeString(String label, String value) {
  writeInt32(null, value.length());
  for (byte letter : value.getBytes()) {
      System.out.println((int)letter);
      writeInt8(null, letter);
  }
}

您正在以字符形式写入长度,然后继续从 getBytes() 写入字节。 getBytes() 对字符串使用平台编码,根据编码是什么,getBytes() 可以返回关于任何东西的信息。

尝试明确指定编码,例如value.getBytes(Charset.forName("ISO-8859-1"));

编辑:还要确保您输出的字符串确实包含您认为它们包含的内容。

【讨论】:

  • 不是downvoter,但这没有用。
  • 在 SO 的第二天不再关心匿名投票了 :)
  • 我写了一些c代码来加载文件,它似乎忽略了0xa。我想知道是否以某种 posix 约定终止带有换行符的文件。
  • @sircodesalot 在您的编辑中最后的所有零来自哪里?看起来您用来生成十六进制转储的任何内容都修改了输入(假设它们来自同一个文件)。您是否偶然将其加载为 text 然后切换到十六进制显示?
  • 我使用的是 256 字节的数组缓冲区,所以也写入了未初始化的内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-11
  • 2017-06-15
  • 1970-01-01
  • 1970-01-01
  • 2013-05-31
相关资源
最近更新 更多