You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中未知类型ProtocolBuffer序列化文件反序列化方法咨询

Got it, let's break down how to tackle this problem—this is super common when dealing with legacy Protobuf data or third-party jars that lack clear documentation. Here's a step-by-step approach to deserialize your sample.dat even without knowing the exact message type upfront:

1. Extract Protobuf Structure Clues from the Jar

First, you need to uncover the hidden Protobuf message definitions in the compiled .class files:

  • Use a Java decompiler like JD-GUI or FernFlower to unpack the jar and decompile classes. Focus on classes that extend com.google.protobuf.GeneratedMessageV3 (or GeneratedMessage for older Protobuf versions)—these are definitely the compiled Protobuf message classes.
  • In each decompiled class, look for field number constants (like public static final int USER_ID_FIELD_NUMBER = 3;) and type hints (e.g., int maps to Protobuf's varint, String maps to length-delimited). Many classes also retain comments or structure details from the original .proto file.
  • Run Protobuf's built-in decode_raw tool to get a raw view of your sample.dat data. This will show you the field numbers and data types present in the serialized data:
    protoc --decode_raw < sample.dat
    
    The output will look something like this, giving you a blueprint to match against the decompiled classes:
    1: varint
    2: length-delimited
    4: fixed32
    
2. Match the Raw Data to a Message Class

Now cross-reference the decode_raw output with the decompiled classes:

  • Compare the field numbers and data types from the raw output to the constants and types in each Protobuf class. The class that has a matching set of field numbers and corresponding types is almost certainly your target message type.
  • If you have multiple candidates, don’t stress—you can test each one programmatically (more on that next) to find the right fit.
3. Test Deserialization Programmatically

Once you have a candidate class, write a quick Java program to verify:

import com.google.protobuf.GeneratedMessageV3;
import java.io.FileInputStream;
import java.io.IOException;

public class ProtobufDeserializer {
    public static void main(String[] args) throws Exception {
        // Replace with the fully qualified name of your candidate class
        Class<? extends GeneratedMessageV3> messageClass = 
            (Class<? extends GeneratedMessageV3>) Class.forName("com.example.MyTargetMessage");
        
        // Read the sample.dat file into a byte array
        byte[] data = readFileToBytes("sample.dat");
        
        // Invoke the parseFrom method to deserialize
        GeneratedMessageV3 message = (GeneratedMessageV3) messageClass
            .getMethod("parseFrom", byte[].class)
            .invoke(null, data);
        
        // Print the deserialized message to confirm
        System.out.println("Success! Deserialized message:\n" + message);
    }

    private static byte[] readFileToBytes(String filePath) throws IOException {
        try (FileInputStream fis = new FileInputStream(filePath)) {
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            return buffer;
        }
    }
}

Just add the jar to your project's classpath and run this. If it prints a readable message without throwing an exception, you’ve found the right type.

4. Generic Fallback Methods

If you want a more automated approach or can’t narrow down the class manually:

  • Auto-scan and test: Write a program that scans all classes in the jar that extend GeneratedMessageV3, then tries to deserialize sample.dat with each one. Catch exceptions for mismatched types and stop when you find a class that works.
  • DynamicMessage: Use Protobuf's DynamicMessage class to deserialize without knowing the exact compile-time class. You’ll need to fetch the Descriptor from the candidate class (via the getDescriptor() method) and use it to parse the raw data:
    import com.google.protobuf.DynamicMessage;
    import com.google.protobuf.Descriptors;
    import java.io.FileInputStream;
    
    public class DynamicDeserializer {
        public static void main(String[] args) throws Exception {
            // Get the descriptor from your candidate class
            Class<?> protoClass = Class.forName("com.example.MyTargetMessage");
            Descriptors.Descriptor descriptor = (Descriptors.Descriptor) protoClass
                .getMethod("getDescriptor")
                .invoke(null);
            
            // Parse the data using DynamicMessage
            try (FileInputStream fis = new FileInputStream("sample.dat")) {
                DynamicMessage message = DynamicMessage.parseFrom(descriptor, fis);
                System.out.println("Deserialized message:\n" + message);
            }
        }
    }
    

内容的提问来源于stack exchange,提问作者Santhosh Tpixler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:51:44