#java #file #binary #datainputstream
#java #файл #двоичный #datainputstream
Вопрос:
Мне нужно прочитать раздел структурированного двоичного файла, передав индекс. Однако DataInputStream не поддерживает пометку / сброс. Как я могу достичь того, чего я хочу? Существуют ли какие-либо другие классы, которые позволяют мне легко достичь этого?
import java.io.*;
import java.io.DataOutputStream;
import java.io.DataInputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;
class Test {
public static int getInt(DataInputStream stream, int index) throws IOException {
int offset = index * 4; // size of int
stream.reset();
stream.skip(offset);
return stream.readInt();
}
public static void main(String[] args) {
String filename = "test.data";
try {
DataOutputStream ostream = new DataOutputStream(new FileOutputStream(filename));
for (int i=0; i<10; i ) {
ostream.writeInt(i);
}
ostream.close();
DataInputStream istream = new DataInputStream(new FileInputStream(filename));
istream.mark(0);
int i0 = getInt(istream, 0);
int i3 = getInt(istream, 3);
int i5 = getInt(istream, 5);
System.out.printf("i0 = %d, i3 = %d, i5 = %dn", i0, i3, i5);
istream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Комментарии:
1. обнаружил, что то, что мне действительно нужно, это RandomAccessFile
2. Похоже, вам не нужна пометка / сброс, поскольку вы читаете данные по порядку. Я бы не стал усложнять ситуацию больше, чем она должна быть.
Ответ №1:
Это не DataInputStream, который не поддерживает пометку / сброс. DataInputStream просто делегирует вызовы для mark / reset базовому потоку (в данном случае FileInputStream). Однако FileInputStream не поддерживает операции пометки / сброса (iirc). Решение этой проблемы заключается в том, чтобы сначала обернуть FileInputStream в BufferedInputStream, прежде чем передавать его в DataInputStream. Это должно позволить использовать требуемые операции. Ie:
DataInputStream istream = new DataInputStream(new BufferedInputStream(new FileInputStream(filename)));
Кроме того, я не совсем уверен, но, насколько я понимаю, вы, возможно, неправильно используете аргумент для mark. Согласно JavaDoc, аргумент означает:
максимальный предел байтов, которые могут быть прочитаны до позиции метки, становится недействительным.
Таким образом, вызов mark с нулевым аргументом не был бы особенно полезен.
Ответ №2:
оберните в BufferedInputStream, он реализует mark
кстати, ваш вызов mark должен выдавать количество байтов, которое вы ожидаете прочитать, пока не произойдет сброс. если вы прочитаете дальше, отметка станет недействительной, и сброс приведет к сбросу
или используйте RandomAccessFile