2017-11-15 5 views
1

Ich versuche, eine Datei mit der Erweiterung mit vmd (Vocaloid Motion Data 0002) zu analysieren. Ich weiß nicht, welche Codierung es verwendet. Ich habe versucht, UTF-8, UTF-16, CS_ASCII und Windows-31j (Shift JIS), aber keiner von ihnen funktioniert (aber basierend auf dem, was ich weiß, sollte die meisten von UTF-8 auflösen, da das Byte für die meisten von 2 ist Figuren).Wie analysiere ich unbekannte Kodierungsdateien?

String testFile = rawFilePath+"/test.vmd"; 
BufferedWriter bw = null; 
FileWriter fw = null; 
fw = new FileWriter(outputPath+"/newFile.txt"); 
bw = new BufferedWriter(fw); 
BufferedReader fBr = new BufferedReader(new InputStreamReader(
    new FileInputStream(testFile), "UTF-8")); //US-ASCII windows-31j 
int count=0; 
String line; 
while ((line = fBr.readLine()) != null) { 
    System.out.println(line); 
    bw.write(line); 
    bw.write("\r\n"); 
    count++; 
    if(count > 3) { //print small portion of a larger file for testing 
     break; 
    } 
    ... 
} 

Sowohl Druck und die Ausgabedatei schreibt so etwas:

???~?N ??????????P ?Z???^?[ ??kkkkkkkk 

Ich habe mich gefragt, ob dies eine Codierung Problem ist, oder ein anderes Problem? Wie parse ich lesbare Daten daraus?

+3

Was macht Sie denken, es ist Textinhalt? Binär-Dateien keine Kodierung haben, und es sei denn, der Verkäufer das Format dokumentiert hat, kann man nicht * decode * die Datei ohne Reverse-Engine es zu schaffen. –

+0

Weil es in der Datei formatter http://mikikikudance.wikia.com/wiki/VMD_file_format im Abschnitt Datei-Header geschrieben wurde – logger

+2

Das ist kein Textdateiformat. Lesen Sie die Dokumentation sorgfältiger. Es ist eine binäre Dateiformatspezifikation. Da der Text an einigen Stellen * string * verwendet, wird es nicht zu einer Textdatei. –

Antwort

1

Vocaloid Bewegungsdaten sind binäre Daten (wie in dem von Ihnen angegebenen Link erwähnt), so dass Sie nicht einfach in Text konvertieren und auf das Beste hoffen können. Das bedeutet, Sie können keine Leser verwenden, müssen aber InputStreams verwenden. Es gibt einen InputStream mit dem Namen DataInputStream, der Ints und Floats lesen kann, wenn sie in VMD auf dieselbe Weise codiert sind wie Java sie erwartet. Sie können es ausprobieren, wenn vernünftige Werte auftauchen, Sie sind golden, sonst müssen Sie die einzelnen Bytes einlesen und mit den Werten berechnen, um das entsprechende Ergebnis selbst zu erzeugen (zB wenn die Daten das am wenigsten signifikante Byte zuerst sind, usw .) Also könnte Code, der in VMD einliest, so aussehen (in Ermangelung einer echten Datei sollte dies nur als Illustration gesehen werden. Es fehlen Dinge wie die Überprüfung, dass wir tatsächlich die Anzahl der Bytes in die Arrays lesen oder.) wenn wir das Ende des Stroms vorzeitig erreicht usw.

try (FileInputStream fis = new FileInputStream(new File("rawFilePath", "test.vmd"))) { 
    DataInputStream dis = new DataInputStream(fis); 
    byte[] nameBytes = new byte[15]; 
    dis.read(nameBytes); 
    int index = 0; 
    for (int i = 0; i < nameBytes.length; i++) { 
     if (nameBytes[i] == 0) { 
      index = i; 
      break; 
     } 
    } 
    String name = new String(nameBytes, 0, index, "8859_1"); 
    // Java ints are signed, so to keep an unsigned int we need long 
    long frameNumber = dis.readInt() & 0xffffffff; 
    float boneXPosCoordinate = dis.readFloat(); 
    float boneYPosCoordinate = dis.readFloat(); 
    float boneZPosCoordinate = dis.readFloat(); 
    float boneXRotCoordinate = dis.readFloat(); 
    float boneYRotCoordinate = dis.readFloat(); 
    float boneZRotCoordinate = dis.readFloat(); 
    float boneWRotCoordinate = dis.readFloat(); 
    byte[] interpolationData = new byte[64]; 
    dis.read(interpolationData); 
} 
+0

Danke, das hat mir geholfen, den richtigen Weg zu gehen. – logger

0

Sie können es als byte Stream untersuchen. Und während dieser Inspektion, dekodieren Sie die ersten paar Bytes von Hand, je nachdem wie die Codierung erfolgt. Eine gute Information über den Start der UTF-Codierung finden Sie unter https://en.wikipedia.org/wiki/Byte_order_mark.

+1

Dies ist nur relevant, wenn Sie wissen, dass Sie eine Textdatei lesen, die dieses Poster nicht ist. Es gibt keine Stückliste im binären Dateninhalt, und wenn Sie auf ähnliche Inhalte in den ersten paar Bytes stoßen, macht es das nicht korrekt. –

+0

Interessant. Die Spezifikationen (https://tools.ietf.org/html/rfc3629#page-6) scheinen einen 'Strom von UCS-Zeichen' anzugeben, der unabhängig vom zugrunde liegenden Speichertyp ist. Es besagt auch, dass es am Anfang des Text-Streams erscheint und dass es optional ist. Es mag also nicht viel Glück geben, diesen Weg zu gehen. –

+0

Die Dateispezifikation, die unter http://mikumikudance.wikia.com/wiki/VMD_file_format zur Verfügung gestellt wird, scheint etwas anderes zu sagen. 4-Byte-Gleitkommazahlen und Ganzzahlen sind kein Text. –