gpt4 book ai didi

java - LittleEndianDataInputStream 是否不稳定,特别是在 Linux 上?

转载 作者:太空宇宙 更新时间:2023-11-04 09:34:00 24 4
gpt4 key购买 nike

我最近接手了学生方程式赛车遥测软件的开发。它使用Java8和JavaFX8。我现在正在尝试修复一个主要错误,但目前我完全陷入困境。该程序可以稍后以自定义格式加载记录的数据以供查看。这在 Mac 和 Windows 上运行良好,但在 Linux 上会引起问题。有些发行版有时会设法加载数据,而有些发行版则根本不管理数据。该问题可能与 LittleEndianDataInputStream 有关。

我还没明白整个问题。所以我想知道是否有人可以向我展示一些“调试”或解决此类问题的方法。并告诉我使用 LittleEndianDataInputStream (不是我实现的)是否是一个好主意(甚至 IntelliJ 也将此 API 标记为不稳定)。如果不是,什么是合适的替代品?由于版本号错误,代码总是从“readVersion()”到达“加载器异常”。从 Windows 加载相同的文件工作正常。

可能

private static Set<Integer> SUPPORTED_VERSIONS = new HashSet<>(Arrays.asList(
1 << 16
));

在操作系统上的计算方式不同?

例如,Fedora 在末尾导致错误日志(每次)。相关代码如下。

private static Set<Integer> SUPPORTED_VERSIONS = new HashSet<>(Arrays.asList(
1 << 16
));

...

public long readTimestampFromHeader(File file) throws LoaderException
{
try(FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
LittleEndianDataInputStream input = new LittleEndianDataInputStream(bis))
{
bytesRead.set(0);
readVersion(input, file);
input.readUnsignedShort(); // ID
readString(input); // Name
readString(input); // Type
return input.readLong();
}
catch(EOFException e)
{
// File corrupt, much too short. Simply ignore
log.log(Level.WARNING, "Could not read record header. Ignoring ...", e);
return 0L;
}
catch(IOException e)
{
throw new LoaderException(file, e);
}
}

private void readVersion(LittleEndianDataInputStream input, File file) throws IOException, LoaderException
{
int version = input.readInt();
bytesRead.set(bytesRead.get() + 4);

if(!SUPPORTED_VERSIONS.contains(version))
{
throw new LoaderException(file, new Exception("File version "
+ version + " is not supported"));
}
}

ErrorLog 的有趣部分:

de.***.***.loader.LoaderException: The loader failed loading from /home/****/****/****/****/***/***/01 - 05.06.2018/Logfiles/1970-01-01-01-01-08/brake_pressure-front.ebl
at de.***.***.loader.ebl.EboxLogReader.readVersion(EboxLogReader.java:155)
at de.***.***.loader.ebl.EboxLogReader.readTimestampFromHeader(EboxLogReader.java:130)

......

Caused by: java.lang.Exception: File version 83946924 is not supported

编辑:总结一下我根据评论或我自己的建议尝试过的事情及其效果:

  • 从 ErrorLog 中手动添加缺少的版本 -> 文件加载到 GUI 中时没有错误,但被称为 08.01.105917131 而不是“xyz.ebl”并且不可用
  • 将 com.google.guava API 的依赖项更新到更高版本不会改变任何内容
  • 简单地将 LittleEndianInputStream 交换为 ObjectInputStream 会产生相同的 ErrorLog,但版本为:256
  • 我尝试加载的文件似乎被写入为 ObjectOutputStream 并且正在被 LittleEndianInputStream 读取。这看起来很奇怪,但只有 Linux 对此有困难。写入文件(我正在尝试加载)是在此处完成的:
public class DataRecordSerializer implements Serializer<DataRecord, FileDataLocator>
{
public static final int VERSION = (0 << 16) + (1 << 8) + 0;

private final boolean append;

public DataRecordSerializer()
{
this(false);
}

public DataRecordSerializer(boolean append)
{
this.append = append;
}

@Override
public void serialize(DataRecord data, FileDataLocator locator) throws SerializerException
{
File target = locator.getFile();
boolean actuallyAppends = this.append && target.exists();

// Save the data
try(FileOutputStream fos = new FileOutputStream(target, this.append);
BufferedOutputStream bos = new BufferedOutputStream(fos);
ObjectOutputStream out = actuallyAppends ?
new AppendingObjectOutputStream(bos) :
new ObjectOutputStream(bos))
{
if(!actuallyAppends)
{
// Version info
out.writeInt(VERSION);

// Save the concrete class
out.writeUTF(data.getClass().getName());

// Header
out.writeObject(data.getHeader());
}

// Data
float[] x = data.getXValues();
float[] y = data.getYValues();

for(int i = 0; i < x.length; i++)
{
out.writeFloat(x[i]);
out.writeFloat(y[i]);
}
}
catch(IOException e)
{
throw new SerializerException(e);
}
}

public static class AppendingObjectOutputStream extends ObjectOutputStream
{
public AppendingObjectOutputStream(OutputStream out) throws IOException
{
super(out);
}

@Override
protected void writeStreamHeader() throws IOException
{
// do not write a header, but reset
reset();
}
}
}

  • 将 Supported_Version 更改为 DataRecordSerializer 中的值
public static final int VERSION = (0 << 16) + (1 << 8) + 0;

没有改变任何东西。之后我将其保留为 Supported_Versions 并再次交换 LittleEndianInputStream 和 ObjectInputStream 并得到此错误日志:

 java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.readFully(ObjectInputStream.java:3106)
at java.io.ObjectInputStream.readFully(ObjectInputStream.java:1076)
at de.*.loader.ebl.EboxLogReader.readString(EboxLogReader.java:158)
at de.*.loader.ebl.EboxLogReader.readTimestampFromHeader(EboxLogReader.java:127)
at de.*.loader.ebl.EboxLogLoader.load(EboxLogLoader.java:65)
at de.*.loader.ebl.EboxLogLoader.load(EboxLogLoader.java:24)
at de.*.loader.LoaderManager.load(LoaderManager.java:122)
at de.*.model.DataManager.forceLoadRunData(DataManager.java:193)
at de.*.model.DataManager.getRunData(DataManager.java:218)
at de.*.gui.fx.job.runData.LoadRunDataJob.call(LoadRunDataJob.java:22)
at de.*.gui.fx.job.runData.LoadRunDataJob.call(LoadRunDataJob.java:8)
at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
WARNING - 26.06.19 19:32:24: Could not read record header. Ignoring ...
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.readFully(ObjectInputStream.java:3106)
at java.io.ObjectInputStream.readFully(ObjectInputStream.java:1076)
at de.*.loader.ebl.EboxLogReader.readString(EboxLogReader.java:158)
at de.*.loader.ebl.EboxLogReader.readHeader(EboxLogReader.java:52)
at de.*.loader.ebl.EboxLogLoader.load(EboxLogLoader.java:86)
at de.*.loader.ebl.EboxLogLoader.load(EboxLogLoader.java:24)
at de.*.loader.LoaderManager.load(LoaderManager.java:122)
at de.*.model.DataManager.forceLoadRunData(DataManager.java:193)
at de.*.model.DataManager.getRunData(DataManager.java:218)
at de.*.gui.fx.job.runData.LoadRunDataJob.call(LoadRunDataJob.java:22)
at de.*.gui.fx.job.runData.LoadRunDataJob.call(LoadRunDataJob.java:8)
at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)

编辑不幸的是,错误没有得到修复,但在重新设计应用程序的这一部分后,困难就消失了,再次感谢所有贡献。

最佳答案

SUPPORTED_VERSIONS 初始化时没有任何元素,并且初始值 1<<16。您可以调试,或尝试:

static {
SUPPORTED_VERSIONS.add(83946924);
}

您没有显示SUPPORTED_VERSIONS的填充,其中由于并发的原因,可能会发生并发、类加载错误。例如,据我所知,Linux 具有更好的并发支持。也许初始化发生在第二个类中,并且类加载出错。

83946924是0x500_EDAC,其中包含一个字节0x00,但我无法想象这样一个类似C的错误,或者与字符串相关的修改后的UTF-8转换,其中0x00也被转换为多字节序列。

也许版本本身就是错误的,应该是 0xACED_0005。

顺便说一句,异常可以简单地编写为:

        throw new LoaderException("File version "
+ version + " is not supported: " + file);

替代类(class):

您可以使用内存映射文件,将 ByteBuffer.order(ByteOrder.LITTLE_ENDIAN); 结合使用。这是标准的java。

关于java - LittleEndianDataInputStream 是否不稳定,特别是在 Linux 上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56737607/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com