如何通过读取C ++中的文件来拆分ByteArray?

时间:2013-09-29 01:13:07

标签: java c++ c bytearray

我编写了一个Java程序来将ByteArray写入文件。结果ByteArray是这三个ByteArrays的结果 -

  • 第一个 2个字节是我schemaId,我用短数据类型代表它。
  • 接下来 8字节是我使用长数据类型表示的Last Modified Date
  • 剩下的字节可以是可变大小,这是我属性的实际值..

所以我现在有一个文件,其中第一行包含生成的ByteArray,它将具有上面提到的所有上述字节。现在我需要从C ++程序读取该文件并读取包含ByteArray的第一行和然后如上所述,相应地分割出生成的ByteArray,这样我就可以从中提取schemaIdLast 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;
}

任何人都可以帮助我吗?感谢。

更新

下面是我的java代码,它会将生成的ByteArray写入一个文件,现在我需要从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();
    }
}

1 个答案:

答案 0 :(得分:1)

您似乎不想使用std::getline来读取此数据。您的文件不是逐行写入文本数据的 - 它基本上都是二进制格式。

您可以使用read的{​​{1}}方法从输入流中读取任意数据块。您可能希望以二进制模式打开文件:

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));

上面的示例仅用于说明如何在C ++中实现此目的。您需要了解以下事项:

  • 上述示例中没有错误检查。您需要检查对ifstream::read的调用是否成功并返回正确数量的数据。
  • Endianness可能是一个问题,具体取决于数据源自和正在阅读的平台。
  • 解释std::unique_ptr<char[]> binaryBuf(new char[binaryLength]); myfile.read(binaryBuf.get(), binaryLength); 字段可能需要您编写一个函数来将其转换为Java使用的任何格式(我不了解Java)。