2011-01-15 6 views
2

Я пытаюсь написать строку в файл в строке-позиции n.Напишите конкретную строку в файл

Даже если строки n нет. В этом случае файл должен расти с пустыми строками, чтобы достигнуть n. В основном что-то вроде writer.writeLine(n, mycontent). mycontent - двоичное представление от ObjectOutputStream. Каждая строка файла содержит сериализованный объект. Номер строки - это индекс.

Как я могу написать конкретную строку? - Без использования FileUtils или любых нестандартных компонентов API.

This answer довольно много подытоживает, что я хочу - но с записью, похоже, ведет себя по-другому.

редактировать: я выяснил мой вопрос в связи с комментариями

+0

BufferedWriter, завернутый в ObjectOutputStream? Можете ли вы это немного разъяснить? –

+2

Ваш вопрос очень неясен. ObjectOutputStream будет записывать двоичные данные - в ObjectOutputStream нет такой концепции, как «строка». –

+0

Извините, я обновил свой вопрос. Я использую номер строки в качестве индекса для повторного поиска сериализованных объектов из файла «container». Проблема в том, что если номер строки является индексом, я должен иметь возможность выбирать, где писать в файле. И я не хочу его полностью кэшировать. – wishi

ответ

2

Является ли понятие линии очень важным для вас? В противном случае вы могли бы сериализовать карту в файле и использовать ее для записи или чтения ваших объектов по определенному индексу (в этом случае индекс будет ключом к карте).

Вот небольшой пример.

public static void main(String[] args) throws Exception { 
    ObjectOutputStream tocStream = new ObjectOutputStream(new FileOutputStream("myfile.toc")); 
    Map<Integer,Object> tableOfContent = new HashMap<Integer, Object>(); 
    String myString = "dataOne"; 
    Date myDate = new Date(); 
    tableOfContent.put(0,myDate); 
    tableOfContent.put(1,myString); 
    tocStream.writeObject(tableOfContent); 
    tocStream.flush(); 
    tocStream.close(); 
    ObjectInputStream tocInputStream = new ObjectInputStream(new FileInputStream("myfile.toc")); 
    Map<Integer,Object> restoredTableOfContent = (Map<Integer, Object>) tocInputStream.readObject(); 
    Object restoredMyString = restoredTableOfContent.get(1); 
    System.out.println(restoredMyString); 
    tocInputStream.close(); 
} 
+0

Я хотел избежать необходимости переписывать. Кажется, это невозможно ... Я не уверен, как реализовать обновления этого файла, содержащие сериализованные объекты. Он может расти. Тем не менее, я думаю, что это впереди. Благодарю. – wishi

0
  • Переберите чтение файлов в текущих значений.
  • Напишите каждое значение из в новый файл temp.
  • Если старый файл заканчивается перед номером вашей строки, держите , выписывая пустые строки.
  • Затем один раз вы получите номер строки, которую вы хотите , чтобы обновить, выписать новые данные.
  • Если есть больше строк для старого файла , продолжайте писать.
  • Удалить старый файл . Переименуйте временный файл.
+0

действительно ли это необходимо? Я не хочу переписывать все только из-за одного изменения. – wishi

+0

Да. Вот почему база данных или какая-либо другая структура для хранения ваших данных может быть лучшим выбором. – jzd

+0

любые простые предложения? У меня нет опыта в этом, и я не хочу сталкиваться со слишком сложной задачей. – wishi

2

Это не сработает, потому что каждый сериализованный объект может содержать один или несколько символов новой строки как часть его двоичного представления. Поэтому, если вы напишете новый объект в строке 3, вы можете очень хорошо написать объект в середине двоичного представления вашего первого. Попробуй:

public class OOSTest { 
    public static void main(String[] args) throws IOException { 
     String s = "Hello\nWorld"; 
     ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
     ObjectOutputStream oos = new ObjectOutputStream(bos); 
     oos.writeObject(s); 
     oos.flush(); 
     oos.close(); 
     System.out.println(new String(bos.toByteArray())); 
    } 
} 

ИМХО, у вас есть три варианта:

  1. выбрать протокол, который будет работать с двоичными данными (например, для каждого объекта, напишите его длину (в байтах) в качестве integer (4 байта), за которым следуют байты самого объекта:
  2. Кодировать сериализованные байты в строку с использованием Base64, например, и использовать разделитель между объектами, которые не являются частью кодировки;
  3. Использовать ObjectOutputStream для seriali ze - массив объектов. Запись новой записи будет заключаться в десериализации массива, убедитесь, что он имеет нужный размер или скопирует его в новый массив соответствующего размера, вставьте объект в его положение и повторно выполните инициализацию всего массива.
+0

, который до сих пор не уточняет, как я могу писать на определенной позиции линии ... Кажется, он становится очень сложным. – wishi

Смежные вопросы