简体   繁体   English

读取输入抛出 java.io.EOFException

[英]Reading an input throws java.io.EOFException

Trying to read an UTF string from byte array throws EOFException, when I know for a fact that it should not happen.当我知道它不应该发生时,尝试从字节数组中读取 UTF 字符串会引发 EOFException。 I've attempted to use ByteBuffer and ByteArrayDataOutputStream and OutputStream for writing the data, and then trying to read it with DataInputStream and ByteArrayDataInputStream and DataInputStream with no success.我尝试使用 ByteBuffer 和 ByteArrayDataOutputStream 和 OutputStream 来写入数据,然后尝试使用 DataInputStream 和 ByteArrayDataInputStream 和 DataInputStream 读取它,但没有成功。 Where am is the code failing and WHY?代码在哪里失败,为什么?

The structure of the data is [String, Long, Long], which translates to String, UUID数据的结构是[String, Long, Long],翻译成String, UUID

Methods I've tried to write the data:我尝试写入数据的方法:

ByteBuffer buffer = ByteBuffer.allocate(g.getID().getBytes().length + Long.BYTES * 2);

buffer.put(g.getID().getBytes());
buffer.putLong(uuid.getMostSignificantBits());
buffer.putLong(uuid.getLeastSignificantBits());
ByteArrayOutputStream output_ = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(output_);
try {           
    output.write(g.getID().getBytes());
    output.writeLong(uuid.getMostSignificantBits());
    output.writeLong(uuid.getLeastSignificantBits());
    api.sendToServers(KaranteeniPermsKeys.GLOBAL_GROUP_CHANGED, output_.toByteArray());
} catch (IOException e) {
    e.printStackTrace();
}

Writing the data with both methods works fine, but the next parts are where it fails:使用这两种方法写入数据都可以正常工作,但接下来的部分是失败的地方:

ByteArrayDataInput input2 = msg.getDataInput();
String group2 = input2.readUTF(); // EOFException
long mostSignificant2 = input2.readLong();
long leastSignificant2 = input2.readLong();
UUID uuid2 = new UUID(mostSignificant2, leastSignificant2);
ByteArrayInputStream input_ = new ByteArrayInputStream(msg.getMessageBytes());
DataInputStream input = new DataInputStream(input_);
try {
    String group = input.readUTF(); // EOFException
    long mostSignificant = input.readLong();
    long leastSignificant = input.readLong();
    UUID uuid = new UUID(mostSignificant, leastSignificant);
    // rest of the code
} catch(IOException e) {
    e.printStackTrace();
}

The data output printed to console results in this: group2��K��&F,��8��m(↑ (Which using string -> bytes converter is '67726f757032efbfbdefbfbd4befbfbdefbfbd26462cefbfbdefbfbd38efbfbdefbfbd6d28e28691') The inputted string is "group2" and inputted UUID is 'd4ef4bc2-db26-462c-9793-389ba56d2818'打印到控制台的数据输出结果如下: group2��K��&F,��8��m(↑ (which using string -> bytes converter is '67726f757032efbfbdefbfbd4befbfbdefbfbd26462cefbfbdefbfbd38efbfbdefbfbd6d28e28691') 输入的字符串是“group2”,输入的 UUID 是'd4ef4bc2-db26-462c-9793-389ba56d2818'

The stacktrace from the above method is the following:上述方法的堆栈跟踪如下:

[14:33:04 WARN]: java.lang.IllegalStateException: java.io.EOFException
[14:33:04 WARN]:        at com.google.common.io.ByteStreams$ByteArrayDataInputStream.readUTF(ByteStreams.java:458)
[14:33:04 WARN]:        at KaranteeniPerms.jar//net.karanteeni.karanteeniperms.spigot.groups.BungeeListeners.onGlobalGroupChanged(BungeeListeners.java:80)                                                        [14:33:04 WARN]:        at SockExchange-1.1.1-all.jar//com.gmail.tracebachi.SockExchange.Messages.ReceivedMessageNotifier.lambda$notify$1(ReceivedMessageNotifier.java:94)                                        [14:33:04 WARN]:        at SockExchange-1.1.1-all.jar//com.gmail.tracebachi.SockExchange.Scheduler.AwaitableExecutor.lambda$wrapTask$0(AwaitableExecutor.java:182)                                                [14:33:04 WARN]:        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
[14:33:04 WARN]:        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
[14:33:04 WARN]:        at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)                                                               [14:33:04 WARN]:        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)                                                                                              [14:33:04 WARN]:        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)                                                                                              [14:33:04 WARN]:        at java.base/java.lang.Thread.run(Thread.java:833)
[14:33:04 WARN]: Caused by: java.io.EOFException
[14:33:04 WARN]:        at java.base/java.io.DataInputStream.readFully(DataInputStream.java:203)
[14:33:04 WARN]:        at java.base/java.io.DataInputStream.readUTF(DataInputStream.java:614)
[14:33:04 WARN]:        at java.base/java.io.DataInputStream.readUTF(DataInputStream.java:570)
[14:33:04 WARN]:        at com.google.common.io.ByteStreams$ByteArrayDataInputStream.readUTF(ByteStreams.java:456)
[14:33:04 WARN]:        ... 9 more 

Minimum reproducible:最小可重复性:

import java.nio.ByteBuffer;
import com.google.common.io.ByteArrayDataInput;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.UUID;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteStreams;


public class MinData {
    public static void main(String[] args) {
        String name = "group2";
        UUID uuid = UUID.randomUUID();
        try {
            method1Input(ByteStreams.newDataInput(method1Output(name, uuid)));
        } catch(Exception e) {
            e.printStackTrace();
        }

        try {
            method1Input(ByteStreams.newDataInput(method2Output(name, uuid)));
        } catch(Exception e) {
            e.printStackTrace();
        }

        try {
            method2Input(method1Output(name, uuid));
        } catch(Exception e) {
            e.printStackTrace();
        }

        try {
            method2Input(method2Output(name, uuid));
        } catch(Exception e) {
            e.printStackTrace();
        }
    }


    public static void method1Input(ByteArrayDataInput input) {
        String group = input.readUTF(); // EOFException
        long mostSignificant = input.readLong();
        long leastSignificant = input.readLong();
        UUID uuid = new UUID(mostSignificant, leastSignificant);
    }


    public static void method2Input(byte[] bytes) {
        ByteArrayInputStream input_ = new ByteArrayInputStream(bytes);
        DataInputStream input = new DataInputStream(input_);
        try {
            String group = input.readUTF(); // EOFException
            long mostSignificant = input.readLong();
            long leastSignificant = input.readLong();
            UUID uuid = new UUID(mostSignificant, leastSignificant);
            // rest of the code
        } catch(IOException e) {
            e.printStackTrace();
        }
    }


    public static byte[] method1Output(String text, UUID uuid) {
        ByteBuffer buffer = ByteBuffer.allocate(text.getBytes().length + Long.BYTES * 2);
        buffer.put(text.getBytes());
        buffer.putLong(uuid.getMostSignificantBits());
        buffer.putLong(uuid.getLeastSignificantBits());
        return buffer.array();
    }


    public static byte[] method2Output(String text, UUID uuid) {
        ByteArrayOutputStream output_ = new ByteArrayOutputStream();
        DataOutputStream output = new DataOutputStream(output_);
        try {           
            output.write("group2".getBytes());
            output.writeLong(uuid.getMostSignificantBits());
            output.writeLong(uuid.getLeastSignificantBits());
            return output_.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

Running the above minimum reproducible produces the following errors:运行上述最小可重现性会产生以下错误:

15:03:34 [SEVERE] java.lang.IllegalStateException: java.io.EOFException
15:03:34 [SEVERE]     at com.google.common.io.ByteStreams$ByteArrayDataInputStream.readUTF(ByteStreams.java:458)
15:03:34 [SEVERE]     at net.karanteeni.karanteeniperms.bungee.KaranteeniPerms.method1Input(KaranteeniPerms.java:101)
15:03:34 [SEVERE]     at net.karanteeni.karanteeniperms.bungee.KaranteeniPerms.<init>(KaranteeniPerms.java:75)
15:03:34 [SEVERE]     at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
15:03:34 [SEVERE]     at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
15:03:34 [SEVERE]     at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
15:03:34 [SEVERE]     at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
15:03:34 [SEVERE]     at net.md_5.bungee.api.plugin.PluginManager.enablePlugin(PluginManager.java:341)
15:03:34 [SEVERE]     at net.md_5.bungee.api.plugin.PluginManager.loadPlugins(PluginManager.java:250)
15:03:34 [SEVERE]     at net.md_5.bungee.BungeeCord.start(BungeeCord.java:271)
15:03:34 [SEVERE]     at net.md_5.bungee.BungeeCordLauncher.main(BungeeCordLauncher.java:67)
15:03:34 [SEVERE]     at net.md_5.bungee.Bootstrap.main(Bootstrap.java:15)
15:03:34 [SEVERE] Caused by: java.io.EOFException
15:03:34 [SEVERE]     at java.io.DataInputStream.readFully(DataInputStream.java:197)
15:03:34 [SEVERE]     at java.io.DataInputStream.readUTF(DataInputStream.java:609)
15:03:34 [SEVERE]     at java.io.DataInputStream.readUTF(DataInputStream.java:564)
15:03:34 [SEVERE]     at com.google.common.io.ByteStreams$ByteArrayDataInputStream.readUTF(ByteStreams.java:456)
15:03:34 [SEVERE]     ... 11 more
15:03:34 [SEVERE] java.lang.IllegalStateException: java.io.EOFException
15:03:34 [SEVERE]     at com.google.common.io.ByteStreams$ByteArrayDataInputStream.readUTF(ByteStreams.java:458)
15:03:34 [SEVERE]     at net.karanteeni.karanteeniperms.bungee.KaranteeniPerms.method1Input(KaranteeniPerms.java:101)
15:03:34 [SEVERE]     at net.karanteeni.karanteeniperms.bungee.KaranteeniPerms.<init>(KaranteeniPerms.java:81)
15:03:34 [SEVERE]     at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
15:03:34 [SEVERE]     at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
15:03:34 [SEVERE]     at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
15:03:34 [SEVERE]     at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
15:03:34 [SEVERE]     at net.md_5.bungee.api.plugin.PluginManager.enablePlugin(PluginManager.java:341)
15:03:34 [SEVERE]     at net.md_5.bungee.api.plugin.PluginManager.loadPlugins(PluginManager.java:250)
15:03:34 [SEVERE]     at net.md_5.bungee.BungeeCord.start(BungeeCord.java:271)
15:03:34 [SEVERE]     at net.md_5.bungee.BungeeCordLauncher.main(BungeeCordLauncher.java:67)
15:03:34 [SEVERE]     at net.md_5.bungee.Bootstrap.main(Bootstrap.java:15)
15:03:34 [SEVERE] Caused by: java.io.EOFException
15:03:34 [SEVERE]     at java.io.DataInputStream.readFully(DataInputStream.java:197)
15:03:34 [SEVERE]     at java.io.DataInputStream.readUTF(DataInputStream.java:609)
15:03:34 [SEVERE]     at java.io.DataInputStream.readUTF(DataInputStream.java:564)
15:03:34 [SEVERE]     at com.google.common.io.ByteStreams$ByteArrayDataInputStream.readUTF(ByteStreams.java:456)
15:03:34 [SEVERE]     ... 11 more
15:03:34 [SEVERE] java.io.EOFException
15:03:34 [SEVERE]     at java.io.DataInputStream.readFully(DataInputStream.java:197)
15:03:34 [SEVERE]     at java.io.DataInputStream.readUTF(DataInputStream.java:609)
15:03:34 [SEVERE]     at java.io.DataInputStream.readUTF(DataInputStream.java:564)
15:03:34 [SEVERE]     at net.karanteeni.karanteeniperms.bungee.KaranteeniPerms.method2Input(KaranteeniPerms.java:112)
15:03:34 [SEVERE]     at net.karanteeni.karanteeniperms.bungee.KaranteeniPerms.<init>(KaranteeniPerms.java:87)
15:03:34 [SEVERE]     at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
15:03:34 [SEVERE]     at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
15:03:34 [SEVERE]     at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
15:03:34 [SEVERE]     at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
15:03:34 [SEVERE]     at net.md_5.bungee.api.plugin.PluginManager.enablePlugin(PluginManager.java:341)
15:03:34 [SEVERE]     at net.md_5.bungee.api.plugin.PluginManager.loadPlugins(PluginManager.java:250)
15:03:34 [SEVERE]     at net.md_5.bungee.BungeeCord.start(BungeeCord.java:271)
15:03:34 [SEVERE]     at net.md_5.bungee.BungeeCordLauncher.main(BungeeCordLauncher.java:67)
15:03:34 [SEVERE]     at net.md_5.bungee.Bootstrap.main(Bootstrap.java:15)
15:03:34 [SEVERE] java.io.EOFException
15:03:34 [SEVERE]     at java.io.DataInputStream.readFully(DataInputStream.java:197)
15:03:34 [SEVERE]     at java.io.DataInputStream.readUTF(DataInputStream.java:609)
15:03:34 [SEVERE]     at java.io.DataInputStream.readUTF(DataInputStream.java:564)
15:03:34 [SEVERE]     at net.karanteeni.karanteeniperms.bungee.KaranteeniPerms.method2Input(KaranteeniPerms.java:112)
15:03:34 [SEVERE]     at net.karanteeni.karanteeniperms.bungee.KaranteeniPerms.<init>(KaranteeniPerms.java:93)
15:03:34 [SEVERE]     at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
15:03:34 [SEVERE]     at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
15:03:34 [SEVERE]     at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
15:03:34 [SEVERE]     at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
15:03:34 [SEVERE]     at net.md_5.bungee.api.plugin.PluginManager.enablePlugin(PluginManager.java:341)
15:03:34 [SEVERE]     at net.md_5.bungee.api.plugin.PluginManager.loadPlugins(PluginManager.java:250)
15:03:34 [SEVERE]     at net.md_5.bungee.BungeeCord.start(BungeeCord.java:271)
15:03:34 [SEVERE]     at net.md_5.bungee.BungeeCordLauncher.main(BungeeCordLauncher.java:67)
15:03:34 [SEVERE]     at net.md_5.bungee.Bootstrap.main(Bootstrap.java:15) 

If you write bytes, you should read them as bytes.如果你写字节,你应该把它们当作字节来读。 If you want a UTF string, then write a UTF string: output.writeUTF(g.getID()) .如果你想要一个 UTF 字符串,那么写一个 UTF 字符串: output.writeUTF(g.getID()) The readUTF method uses something to determine where to stop reading. readUTF方法使用某些东西来确定在哪里停止阅读。 I've checked the OpenJDK source code of DataInputStream , and its readUTF method expects the string length first (2 bytes), then it reads that many characters.我检查了DataInputStream的 OpenJDK 源代码,它的readUTF方法首先需要字符串长度(2 个字节),然后读取那么多字符。 This is documented in DataInput.readUTF这记录在DataInput.readUTF

First, two bytes are read and used to construct an unsigned 16-bit integer in exactly the manner of the readUnsignedShort method .首先,读取两个字节并使用 readUnsignedShort 方法的方式构造一个无符号的 16 位整数。 This integer value is called the UTF length and specifies the number of additional bytes to be read.这个整数值称为 UTF 长度,并指定要读取的附加字节数。 These bytes are then converted to characters by considering them in groups.然后通过分组考虑将这些字节转换为字符。 The length of each group is computed from the value of the first byte of the group.每个组的长度是根据组的第一个字节的值计算的。 The byte following a group, if any, is the first byte of the next group.组后面的字节(如果有的话)是下一组的第一个字节。

So you can do the same with a ByteBuffer as well.所以你也可以对ByteBuffer做同样的事情。 First write the size as a short, then the bytes as UTF8:首先将大小写为short,然后将字节写为UTF8:

var bytes = string.getBytes(StandardCharsets.UTF_8);
buffer.putShort((short) bytes.length);
buffer.put(bytes);

Note the explicit conversion to bytes using UTF-8.请注意使用 UTF-8 显式转换为字节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM