0

ByteArrayをファイルに書き込むJavaプログラムを作成しました。その結果ByteArrayは、これら 3 つの ByteArrays の結果です。

  • 最初の2 バイトは、schemaId短いデータ型を使用して表現したものです。
  • 次に、次の8 バイトは、Last Modified Date長いデータ型を使用して表現したものです。
  • 残りのバイトは、属性の実際の値である可変サイズにすることができます..

したがって、最初の行に上記のすべてのバイトが含まれる結果の ByteArray が含まれるファイルができました。次に、C++ プログラムからそのファイルを読み取り、ByteArray を含む最初の行を読み取り、それを分割する必要があります。上記のように、それに応じて結果の ByteArray を取得し、そこから my と実際の属性値を抽出できるようにしschemaIdますLast Modified Date

私はすべてのコーディングを常に Java で行っており、C++ は初めてです... C++ でプログラムを記述してファイルを読み取ることはできますが、その ByteArray をどのように読み取ればよいかわかりません。上記のように分割します。

以下は、ファイルを読み取り、コンソールに出力する私の C++ プログラムです。

int main () {
    string line;

    //the variable of type ifstream:
    ifstream myfile ("bytearrayfile");

    //check to see if the file is opened:
    if (myfile.is_open())
    {
        //while there are still lines in the
        //file, keep reading:
        while (! myfile.eof() )
        {
            //place the line from myfile into the
            //line variable:
            getline (myfile,line);

            //display the line we gathered:
            // and here split the byte array accordingly..
            cout << line << endl;
        }

        //close the stream:
        myfile.close();
    }

    else cout << "Unable to open file";

    return 0;
}

誰でもそれで私を助けることができますか?ありがとう。

アップデート

以下は、結果のByteArrayをファイルに書き込む私のJavaコードであり、同じファイルをc ++から読み戻す必要があります..

public static void main(String[] args) throws Exception {

    String os = "whatever os is";
    byte[] avroBinaryValue = os.getBytes();

    long lastModifiedDate = 1379811105109L;
    short schemaId = 32767;

    ByteArrayOutputStream byteOsTest = new ByteArrayOutputStream();
    DataOutputStream outTest = new DataOutputStream(byteOsTest);
    outTest.writeShort(schemaId);
    outTest.writeLong(lastModifiedDate);
    outTest.writeInt(avroBinaryValue.length);
    outTest.write(avroBinaryValue);

    byte[] allWrittenBytesTest = byteOsTest.toByteArray();

    DataInputStream inTest = new DataInputStream(new ByteArrayInputStream(allWrittenBytesTest));

    short schemaIdTest = inTest.readShort();

    long lastModifiedDateTest = inTest.readLong();

    int sizeAvroTest = inTest.readInt();
    byte[] avroBinaryValue1 = new byte[sizeAvroTest];
    inTest.read(avroBinaryValue1, 0, sizeAvroTest);


    System.out.println(schemaIdTest);
    System.out.println(lastModifiedDateTest);
    System.out.println(new String(avroBinaryValue1));

    writeFile(allWrittenBytesTest);
}

    /**
 * Write the file in Java
 * @param byteArray
 */
public static void writeFile(byte[] byteArray) {

    try{
        File file = new File("bytearrayfile");

        FileOutputStream output = new FileOutputStream(file);
        IOUtils.write(byteArray, output);           
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}
4

1 に答える 1

1

std::getlineこのデータの読み取りに使用したくないようです。ファイルは行ごとにテキスト データとして書き込まれるのではなく、基本的にバイナリ形式です。

readのメソッドを使用してstd::ifstream、入力ストリームからデータの任意のチャンクを読み取ることができます。ファイルをバイナリ モードで開きたい場合は、次のようにします。

std::ifstream myfile("bytearrayfile", std::ios::binary);

基本的に、ファイルから各レコードを読み取るために使用する方法は次のとおりです。

uint16_t schemaId;
uint64_t lastModifiedDate;
uint32_t binaryLength;

myfile.read(reinterpret_cast<char*>(&schemaId), sizeof(schemaId));
myfile.read(reinterpret_cast<char*>(&lastModifiedDate), sizeof(lastModifiedDate));
myfile.read(reinterpret_cast<char*>(&binaryLength), sizeof(binaryLength));

これにより、データ構造の 3 つの静的メンバーがファイルから読み取られます。データは可変サイズであるため、おそらく次のように、データを読み取るためのバッファーを割り当てる必要があります。

std::unique_ptr<char[]> binaryBuf(new char[binaryLength]);
myfile.read(binaryBuf.get(), binaryLength);

上記は、C++ でこれにどのようにアプローチするかを示すための例にすぎません。次の点に注意する必要があります。

  • 上記の例にはエラー チェックはありません。ifstream::readの呼び出しが成功し、正しい量のデータが返されることを確認する必要があります。
  • エンディアンが問題になる場合があります。これは、データの発生元であり、読み取られているプラ​​ットフォームによって異なります。
  • フィールドを解釈するlastModifiedDateには、Javaが使用する形式から変換する関数を作成する必要がある場合があります(Javaについてはわかりません)。
于 2013-09-29T02:33:38.010 に答える