Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ReadInt()返回荒谬的值_Java_File_Int_Persistence - Fatal编程技术网

Java ReadInt()返回荒谬的值

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){

我有一个在.dat文件中存储int的方法(除其他外),后来我尝试用另一个方法检索它,它给出了一个荒谬的值。例如,如果我尝试存储1,则另一个方法检索484449。我是Java新手,所以如果这是正常的,请解释

写入int的方法:

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();
}