DataOutputStream
具有转换基元值的方法
键入一个字节序列,然后将其写入底层
流。
如何使用OutputStream
模拟转化(例如,
FileOutputStream
),了解DataOutputStream
目的?这是我的尝试:
try(FileOutputStream fout = new FileOutputStream("myfile")){
Random random = new Random();
for (int i=0; i<100; i++){
int tmp = random.nextInt();
System.out.println(tmp);
fout.write((byte[])tmp); // error: incompatible types: int cannot be converted to byte[]
}
} catch (IOException e){
System.err.println(e);
}
但我收到的是(byte[])tmp
:
error: incompatible types: int cannot be converted to byte[]
为什么我无法将int
投射到byte[]
?
我该如何模拟转换?
如果我有一个int
数组,我可以使用FileOutputStream
的单个写方法模拟转换,而不是每个元素的元素调用一次write方法吗?
感谢。
答案 0 :(得分:0)
我想知道转换是如何完成的?
最简单的方法是阅读代码或Javadoc。
/**
* Writes an <code>int</code> to the underlying output stream as four
* bytes, high byte first. If no exception is thrown, the counter
* <code>written</code> is incremented by <code>4</code>.
*
* @param v an <code>int</code> to be written.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#out
*/
public final void writeInt(int v) throws IOException {
out.write((v >>> 24) & 0xFF);
out.write((v >>> 16) & 0xFF);
out.write((v >>> 8) & 0xFF);
out.write((v >>> 0) & 0xFF);
incCount(4);
}
转换是否不会更改存储在内存中的数据,而是将基本类型的数据重新解释为字节序列?
没有
那么我该如何模拟转换?
你不能Java不玩那些技巧。
注意:您可以使用Unsafe
类执行此操作,但除非没有其他选择,否则应避免使用它,因为它不安全
你在哪里找到“代码”?
您可以通过点击课程或搜索课程在IDE中找到它,也可以谷歌查看来源。
为什么我不能将int转换为byte []
Java中没有这样做的定义。例如它应该是小端还是大端?请注意byte[]
是一个对象。
为什么代码并不意味着“转换不会改变存储在内存中的数据,而是将原始类型的数据重新解释为字节序列?”
没有Java语言可以做到这一点。有一些低级库工具可以执行此操作,但这些工具具有非常具体的用例。
答案 1 :(得分:0)
如何从
int
转换为byte[]
?
这是一段将进行转换的代码。
对于后来的读者:向下滚动以查看将整数数组转换为字节数组的示例。
我将在下面解释这段代码。
static byte[] convertIntToByteArray(int x)
{
// This assumes that int is 32-bit and has a size of 4 bytes
byte[] b = new byte[4];
b[i] = ((x >>> 24) & 0xFF);
b[i] = ((x >>> 16) & 0xFF);
b[i] = ((x >>> 8) & 0xFF);
b[i] = ((x >>> 0) & 0xFF);
return b;
}
此代码是将int
拆分为byte[]
的低效但兼容的方式。它手动使用位掩码(如DataOutputStream
)来操作每个字节。
但是,理论上你是正确的。 int
表示为内存中的单个字节,但软件会为您抽象。
注意:您也可以使用Unsafe
类来执行此操作。但是,它并不完全安全(用讽刺阅读),并且它很容易受到Java内部布局和平台差异的影响。此外,甲骨文一直试图杀死Unsafe
一段时间。因此,上面的方法是一种较慢但非常兼容的处理方法,如果你不试图编写模拟器,那么你应该能够摆脱性能损失。
无需模拟转换。只需使用DataOutputStream
。
但是,如果您真的想要模拟它,可以创建一个byte[]
数组并手动将ints
放入其中,然后将其传递给ByteArrayOutputStream
,如下所示。这基本上复制了Java中的现有功能,我建议使用内置函数,因为它们几乎可以保证比您的更优化。我从上面的彼得的答案中借用了一些代码。
byte[] b = new byte[Integer.SIZE*4]; // large enough to hold 4 int vars (each int is guaranteed to be Integer.SIZE bytes)
int[] a = new int[4];
for(int i = 0, j = 0; i < b.length; i+=Integer.SIZE, j++)
{
b[i] = ((a[j] >>> 24) & 0xFF);
b[i] = ((a[j] >>> 16) & 0xFF);
b[i] = ((a[j] >>> 8) & 0xFF);
b[i] = ((a[j] >>> 0) & 0xFF);
}
FileOutputStream fo = new FileOutputStream("[your filename here]"); // WARNING: In real code, you need to handle the FileNotFoundException
fo.write(b);
fo.close();