1

我致力于创建游戏。我想隐藏我所有的 .tga 文件。我将我所有文件的字符串内容连接到一个文件中,以使其对玩家不可见。我希望我的程序通过从保存的内容创建临时 .tga 文件来加载图片。

因此,我正在尝试从原始内容中复制 .tga 文件。更准确地说,我将 .tga 文件作为文本读取并写入。尽管 Notepad++ 发现原始文件和新文件相同,但新文件不能作为 .tga 文件打开。Windows 检测具有 1 字节偏移量的文件的大小。

你能解释一下我做错了什么吗?或者可能会建议我一个更好的方法来隐藏我的文件。

问候

4

2 回答 2

0

更准确地说,我将 .tga 文件作为文本读取并写入

这可能是您的问题:您必须将 .tga 文件作为二进制文件进行读写。否则,字节序列 0x0D 0x0A(CR LF,Windows 行结束)的任何出现都可能被单个 0x0A(LF,Unix 行结束)替换,反之亦然,或者 0x1A(文件的 DOS 结束)可能被剥离或附加。根据您使用的代码,您还可能最终剥离任何 0x00 (NUL) 字节。

于 2019-01-27T19:14:19.297 回答
0

我试图用我的程序(c++)读/写一个 .tga 文件作为二进制文件,但生成的文件仍然损坏。代码如下。

std::string name = "my_picture.tga";
std::ifstream FileIn(name, std::ios_base::binary);
std::vector<char> listChar;
bool stopp = false;
if (FileIn) {
    while (!(stopp))
    {
        char xin;
        FileIn.read(reinterpret_cast<char*>(&xin), sizeof(char));
        listChar.push_back(xin);
        if (FileIn.eof()) stopp = true;
    }
    FileIn.close();
}

std::ofstream FileOut(".\\test.tga", std::ios_base::binary);
bool isCarierReturn = false;
for (char xout : listChar) {
    isCarierReturn = xout == '\r';
    if (!isCarierReturn) FileOut.write(reinterpret_cast<const char*>(&xout), sizeof(char));
}
FileOut.close();

我在十六进制阅读器上比较了原始文件和新文件,文件实际上是不同的。

原始文件和新文件之间的区别在于行尾不匹配,而不是原始文件上只有 0x0A ('\n'),新文件具有字节序列 0x0D 0x0A ('\r' 和 '\n' )。在其他一些图片上,生成的文件不完整,中断总是在 0x1A 值之前(如@Christoph Lipka 所说)。

我设法通过测试 char 是否是载波返回来编写正确的序列,在这种情况下没有写入 char,只跳过了字节 0x0D,见下文:

std::ofstream FileOut(".\\test.tga", std::ios_base::binary);
bool isCarrierReturn = false;
char xout_p1 = '\0';
if (listChar.size() >= 1) xout_p1 = listChar.at(0);
for (unsigned i(0); i < listChar.size(); i++) {
    char xout = xout_p1;
    if (i < listChar.size() - 1) xout_p1 = listChar.at(i + 1);
    else xout_p1 = '\0';
    isCarrierReturn = xout == '\r' && xout_p1 == '\n';
    if (!isCarrierReturn) FileOut.write(reinterpret_cast<const char*>(&xout), sizeof(char));
}
FileOut.close();

通过将文件读取为二进制文件来解决文件读取不完整的问题。

有用。

于 2019-01-30T22:01:07.683 回答