Java ReadInt()返回荒谬的值
我有一个在.dat文件中存储int的方法(除其他外),后来我尝试用另一个方法检索它,它给出了一个荒谬的值。例如,如果我尝试存储1,则另一个方法检索484449。我是Java新手,所以如果这是正常的,请解释 写入int的方法:Java ReadInt()返回荒谬的值,java,file,int,persistence,Java,File,Int,Persistence,我有一个在.dat文件中存储int的方法(除其他外),后来我尝试用另一个方法检索它,它给出了一个荒谬的值。例如,如果我尝试存储1,则另一个方法检索484449。我是Java新手,所以如果这是正常的,请解释 写入int的方法: public static int fromText (String textRefference, String binaryRefference, boolean overwrite, String countRefference){
public static int fromText (String textRefference, String binaryRefference,
boolean overwrite, String countRefference){
if(!(new File(binaryRefference).exists()))overwrite = true;
BufferedReader input;
ObjectOutputStream output;
ObjectInputStream binaryInput;
ObjectInputStream countStreamI;
ObjectOutputStream countStreamO;
int count = 0;
try{
input = new BufferedReader(new FileReader(textRefference));
String[] data = null;
int oldCount = 0;
if(!overwrite){
countStreamI = new ObjectInputStream(new FileInputStream(countRefference));
binaryInput = new ObjectInputStream(new FileInputStream(binaryRefference));
oldCount = countStreamI.readInt();
data = new String[oldCount];
int i;
for(i = 0;i < oldCount; i++){
data[i] = binaryInput.readUTF();
}
countStreamI.close();
}
countStreamO = new ObjectOutputStream(new FileOutputStream(countRefference));
output = new
ObjectOutputStream(new FileOutputStream(binaryRefference));
String sentinel = input.readLine();
String[] data2 = new String[1500];
while(!sentinel.equalsIgnoreCase("end")){
System.out.println(sentinel + " has been recorded");
data2[count] = sentinel;
sentinel = input.readLine();
count++;
}
count += oldCount;
countStreamO.writeInt(count);
if(!overwrite){
int i;
for(i = 0; i < oldCount;i++){
output.writeUTF(data[i]);
}
}
int i = 0;
for(; i < count + oldCount;i++){
output.writeUTF(data2[i]);
}
output.flush();
countStreamO.flush();
countStreamO.close();
output.close();
input.close();
}
catch(Exception e){
Scanner in = new Scanner(System.in);
e.printStackTrace();
in.nextLine();
System.exit(0);
}
return count;
}'
这个奇怪的数字,484449,实际上是读取四个字节的结果:00076461 这些字节是从哪里来的?嗯,出于某种原因,您选择使用
countStreamO.writeInt(count)将count
发送到另一个文件代码>。因此,当您的检索代码执行input.readInt()
时,它希望在同一个文件中找到一个计数,但您从未在其中编写过
相反,您将计数发送到另一个文件,然后继续使用output.writeUTF(data[i])
和output.writeUTF(data2[i])
将每个字符串写入主数据文件
writeUTF实际上做什么?好的,ObjectOutputStream.writeUTF的文档并没有对此做太多说明,只是该方法是由DataOutput接口强制执行的。不过,这本书提供了相当丰富的信息:
将两个字节的长度信息写入输出流,然后修改字符串s
中每个字符的UTF-8表示形式
因此,您从未将count
值写入该文件,但确实向其发送了字符串“data!!!”。现在我们知道writeUTF首先写入该字符串的字节长度(将其转换为修改后的UTF-8),然后写入修改后的UTF-8字节本身
在本例中,您的字符串完全由ASCII字符组成,当用修改的UTF-8(或真正的UTF-8)编码时,每个字符占用一个字节,而不需要编码。因此字符串需要7个字节,每个字符一个字节
也就是说,writeUTF方法为字节长度(0007)写入两个字节,然后为字符(6461746121)写入七个字节
这意味着文件中的前四个字节是00 07 64 61。您试图将它们读取为32位int,因此得到0x00076461或484449
您的代码比需要的复杂得多。这种复杂性使得我们很难看到像这样的小问题。另外,一些文档会清楚地说明代码应该做什么。当您开始编写检索代码时,您似乎意识到,计数不需要单独的文件,但您从未返回并更新写入数据的代码以适应改进
我不知道您的数据文件是否需要遵循外部指定的格式,但如果不需要,您可以通过完全取消计数,取消readUTF和writeUTF来轻松完成任务。相反,您可以简单地序列化字符串数组:
String[] allData = new String[data.length + data2.length];
System.arraycopy(data, 0, allData, 0, data.length);
System.arraycopy(data2, 0, allData, data.length, data2.length);
try (ObjectOutputStream out = new ObjectOutputStream(
new BufferedOutputStream(
new FileOutputStream(binaryReference)))) {
out.write(allData);
}
长度是数组对象状态的一部分,因此它包含在序列化输出中
阅读它更容易:
String[] data;
try (ObjectInputStream in = new ObjectInputStream(
new BufferedInputStream(
new FileInputStream(file)))) {
data = (String[]) in.readObject();
}
您的问题本质上是,“为什么我没有向您展示的代码不起作用?”
。请通过创建和发布您的代码来解决此问题。如果出现错误,请始终发布您的代码和错误。一个简单的描述不足以帮助您。您可以与我们共享这些功能吗?如果没有代码示例,就很难帮助您。“我不熟悉Java,因此如果这是正常的,请解释。”--您听说过哪些计算机语言在某种程度上是正常的吗?我发布了代码。还有@azurefrog Java做的一些事情对我来说是陌生的,来自c#。所以我想我可能需要进行某种类型的转换。
String[] allData = new String[data.length + data2.length];
System.arraycopy(data, 0, allData, 0, data.length);
System.arraycopy(data2, 0, allData, data.length, data2.length);
try (ObjectOutputStream out = new ObjectOutputStream(
new BufferedOutputStream(
new FileOutputStream(binaryReference)))) {
out.write(allData);
}
String[] data;
try (ObjectInputStream in = new ObjectInputStream(
new BufferedInputStream(
new FileInputStream(file)))) {
data = (String[]) in.readObject();
}