Как правильно записать / прочитать файл с разными потоками ввода-вывода? - PullRequest
2 голосов
/ 23 апреля 2011

У меня есть файл, который содержит байты, символы и объект, которые нужно записать и прочитать.Как лучше всего использовать разные потоки ввода-вывода Java для записи и чтения этих типов данных?Точнее говоря, существует ли правильный способ добавить разделители и распознать эти разделители, а затем запустить какой поток следует использовать?Я считаю, что мне нужны некоторые пояснения по использованию нескольких потоков в одном файле, что я никогда раньше не изучал.Подробное объяснение будет достаточным ответом.Спасибо!

Ответы [ 6 ]

2 голосов
/ 24 апреля 2011

Как уже предложено EJP , используйте ObjectOutputStream и ObjectInputStream и оберните остальные элементы как объект (ы). Я даю в качестве ответа, чтобы я мог показать пример (это трудно сделать в комментарии) EJP - если вы хотите встроить его в свой вопрос, пожалуйста, сделайте, и я удалю ответ.

class MyWrapedData implements serializeable{
    private String string1;
    private String string2;
    private char   char1;
    // constructors
    // getters setters
}

Запись в файл:

ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(fileName));
out.writeObject(myWrappedDataInstance);
out.flush();

Чтение из файла

ObjectInputStream in = new ObjectInputStream(new FileInputStream(fileName));
Object obj = in.readObject();
MyWrapedData wraped = null;
if ((obj != null) && (obj instanceof MyWrappedData))
    wraped = (MyWrapedData)obj;
// get the specific elements from the wraped object

см. Очень ясный пример здесь: Чтение и Запись

1 голос
/ 23 апреля 2011

Редизайн файла. Не существует разумного способа его реализации, как в настоящее время разработано. Например, объект предполагает ObjectOutputStream, у которого есть заголовок - куда это пойдет? И как вы узнаете, где перейти от байтов к символам?

Я бы, вероятно, использовал бы ObjectOutputStream для всего этого и записал бы все как объекты. Тогда Сериализация решит все эти проблемы для вас. В конце концов, вам все равно, что находится в файле, только как читать и писать.

0 голосов
/ 31 мая 2011

Если структура вашего файла не фиксирована, рассмотрите возможность использования оболочки для каждого типа. Сначала вам нужно создать интерфейс ваших классов-обёрток….

interface MyWrapper extends Serializable {
    void accept(MyWrapperVisitor visitor);
}

Затем вы создаете интерфейс MyWrapperVisitor…

interface MyWrapperVisitor {
    void visit(MyString wrapper);
    void visit(MyChar wrapper);
    void visit(MyLong wrapper);
    void visit(MyCustomObject wrapper);
}

Затем вы создаете классы-обёртки…

class MyString implements MyWrapper {
    public final String value;

    public MyString(String value) {
        super();
        this.value = value;
    }

    @Override
    public void accept(MyWrapperVisitor visitor) {
        visitor.visit(this);

    }
}
.
.
.

И, наконец, вы читаете свои объекты ...

final InputStream in = new FileInputStream(myfile);
final ObjectInputStream objIn = new ObjectInputStream(in);
final MyWrapperVisitor visitor = new MyWrapperVisitor() {
    @Override
    public void visit(MyString wrapper) {
        //your logic here

    }
    .
    .
    .
};

//loop over all your objects here
final MyWrapper wrapper = (MyWrapper) objIn.readObject();
wrapper.accept(visitor);
0 голосов
/ 24 апреля 2011

Если у вас есть контроль над форматом файла, и это не очень большой файл (например, <1 ГиБ), задумывались ли вы об использовании протокольных буферов Google? </p>

Они генерируют код, который анализирует (и сериализует)содержимое файла / байта [].Протоколные буферы используют подход тегирования для каждого значения, которое включает (1) номер поля и (2) тип, поэтому они имеют хорошие свойства, такие как прямая / обратная совместимость с необязательными полями и т. Д. Они довольно хорошо оптимизированы как для скорости, так и для размера файла.добавление только ~ 2 байтов служебной информации для короткого байта [], с ~ 2-4 дополнительными байтами для кодирования длины в больших полях byte [] (длины, закодированные VarInt).

Это может быть излишним, ноесли у вас есть куча различных полей и типов, protobuf действительно полезен.См .: http://code.google.com/p/protobuf/.

Альтернативой является Thrift от Facebook, с поддержкой еще нескольких языков, хотя, возможно, в последнем, когда я проверял, диком использовании меньше.

0 голосов
/ 23 апреля 2011

Почему бы не записать файл в формате XML, возможно, с хорошей простой библиотекой, такой как XSTream.Если вас беспокоит пространство, поместите его в сжатие gzip.

0 голосов
/ 23 апреля 2011

Можете ли вы изменить структуру файла? Это неясно, потому что первое предложение вашего вопроса противоречит возможности добавления разграничителей. Если вы можете изменить структуру файла, вы можете вывести разные типы данных в отдельные файлы. Я считаю, что это «правильный» способ разграничения потоков данных.

Если вы застряли с файлом таким, какой он есть, вам нужно написать интерфейс к структуре файла, который на практике представляет собой список покупок операций чтения и обработки исключений. Хакерский способ программирования, потому что он потребует шестнадцатеричный редактор и много проб и ошибок, но в некоторых случаях он работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...