RandomAccessFile.write に指示した内容が書き込まれません
-
11-09-2019 - |
質問
やあ、皆さん。ある SQL 形式のファイルから別の SQL 形式のファイルを読み取っているのですが、途中の 2 バイトが破損しています。これは、私が行っていない準備または安全対策だったのだと思います。
破損したデータの例:
//From the file that is read from. added ** to emphasize the corrupted byte
insert into viruses (virusSig,virusHash) values (
X'579fdc569b170419e15750f0feb360aa9c58d8**90**eede50def97ee7cb03b9e905',
X'ee002fe5');
//From the file that is written to. added ** to emphasize the corrupted byte
insert into changes (filepath,loc,dat,vir,hash) values (
'E:\MyDocs\intel\antivirus\RandomFiles\0\2\5\11\24\49\EG1AxxeJSr.data',
243540,
X'9f4246ff8c73c5a5b470cab8c38416929c4eacc1e0021d5ac1fdbb88145d3e6f',
X'579fdc569b170419e15750f0feb360aa9c58d8**3f**eede50def97ee7cb03b9e905',
X'6546dd27');
以下から読み取り/書き込みを行うコード:
public static void insertViruses(FileLocation[] locations, byte[][] viruses, String logpath)
{
int numViruses = viruses.length;
int virusLength = GenerateRandomCorpus.virusSignatureLengthInBytes;
try{
for (int i = 0; i < numViruses; i++)
{
FileOutputStream logwriter = new FileOutputStream(logpath, true);
// Prep to copy section
int locationOfChange = locations[i].index;
String filepathToChange = locations[i].filepath;
File checkIfBackupExists = new File(filepathToChange + ".bak");
if (!checkIfBackupExists.exists())
copyFile(filepathToChange, filepathToChange + ".bak");
copyFile(filepathToChange, filepathToChange + ".tmp");
RandomAccessFile x = new RandomAccessFile(filepathToChange, "rw");
x.seek(locationOfChange);
// Copy section into byte array to write in log
byte[] removedSection = new byte[virusLength];
x.read(removedSection, 0, virusLength);
if (GenerateRandomCorpus.dbg)
System.out.println(filepathToChange + ":" + locationOfChange);
x.close();
// Write changes to log
byte[] removedSectionConvertedToHexString = StringUtils.getHexString(removedSection).getBytes();
byte[] virusConvertedToHexString = StringUtils.getHexString(viruses[i]).getBytes();
byte[] hashConvertedToHexString = StringUtils.getHexString(GenerateRandomViruses.intToByteArray(new String(viruses[i]).hashCode())).getBytes();
System.out.println(StringUtils.getHexString(removedSection));
System.out.println(StringUtils.getHexString(viruses[i]));
logwriter.write(String.format("insert into changes (filepath,loc,dat,vir,hash) values " +
"('%s',%d,X'", filepathToChange, locationOfChange).getBytes());
logwriter.write(removedSectionConvertedToHexString);
logwriter.write("',X'".getBytes());
logwriter.write(virusConvertedToHexString);
logwriter.write("',X'".getBytes());
logwriter.write(hashConvertedToHexString);
logwriter.write("');\n".getBytes());
// Insert virus into file
File original = new File(filepathToChange);
original.delete();
RandomAccessFile fileToInsertIn = new RandomAccessFile(filepathToChange + ".tmp", "rw");
fileToInsertIn.seek(locationOfChange);
fileToInsertIn.write(viruses[i]);
fileToInsertIn.close();
File a = new File(filepathToChange + ".tmp");
original = new File(filepathToChange);
a.renameTo(original);
a.delete();
logwriter.close();
}
} catch (Exception e)
{
System.err.println(e.toString());
System.err.println("Error: InsertVirusesIntoCorpus, line 100");
}
}
何か案は?
解決
あなたのコードと、なぜこれほど多くの変換が起こっているのか少し当惑していますが、それでは...
私の直感では、意図せずに文字セット変換が行われているか、生のバイト、Java バイト プリミティブ、および Java int プリミティブの間での移動が破損の原因であるかのどちらかだと思います。Java を覚えておいてください。 byte
値の範囲は -127 ~ 128 であり、その String の .getBytes() は文字エンコード スキームを認識します。
具体的に言うと、これは私には非常に奇妙に思えます。
byte[] virusConvertedToHexString = StringUtils.getHexString(viruses[i]).getBytes();
これが起こっていることです:
viruses[i]
をあなたに与えていますbyte
配列StringUtils.getHexString()
そのバイト配列を取得し、それを 16 進数で表現します。byte
配列としてString
(仮定:これは何ですかStringUtils
?からではないようです[org.apache.commons.lang][1]
.)- 最後に、保存しているのは、
String
さんのbyte
配列にvirusConvertedToHexString
ステップ 2 は、トラブルが疑われる場合です。
また、上記のコード ブロックには、以下を生成するコードは含まれていません。
//From the file that is read from. added ** to emphasize the corrupted byte
insert into viruses (virusSig,virusHash) values (
X'579fdc569b170419e15750f0feb360aa9c58d8**90**eede50def97ee7cb03b9e905',
X'ee002fe5');
それは役立つでしょう。
所属していません StackOverflow