Предложение о хранении значений в файле в Java? - PullRequest
1 голос
/ 26 июня 2011

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

Но есть ли что-то особенное, что я должен учитывать для выполнения таких задач в Java. Например, мне нужно сериализовать его или, может быть, сделать что-то особенное. Есть ли что-то, что я должен позаботиться о том, чтобы делать такие вещи, где я храню важные данные об использовании приложения. Должно ли это быть просто ASCII / xml или как?
Данные не являются конфиденциальными, однако важна целостность данных.

Ответы [ 5 ]

2 голосов
/ 26 июня 2011

Если ваши данные действительно огромные, я бы порекомендовал некоторую двоичную форму - это сделает ее меньше и быстрее для чтения и особенно для анализа (XML или JSON во много раз медленнее, чем чтение / запись двоичных данных).Сериализация также приносит много накладных расходов, поэтому вы можете проверить DataInputStream и DataOutputStream.Если вы знаете, что будете писать только числа определенного типа, или знаете, в какой последовательности будут находиться данные - это, безусловно, самые быстрые.

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

Что-то вроде (примерный размер буфера 8192 - вы можете настроить его под свои нужды):

    final File file = null; // get file somehow
    final DataOutputStream dos = new DataOutputStream(
       new BufferedOutputStream(new FileOutputStream(file), 8192));
    try {
        for (int x: ....) { //loop through your matrix (might be different if matrix is sparse)
           for (int y: ....) {
               if (matrix[x,y] != 0.0) {
                   dos.writeInt(x);
                   dos.writeInt(y);
                   dos.writeDouble(matrix[x,y]);                                     
               } 
           }
        }
     } finally {
       dos.writeInt(-1); // mark end (might be done differently)
       dos.close();
     }

и ввод:

    final File file = null; // get file somehow
    final DataInputStream dis = new DataInputStream(
      new BufferedInputStream(new FileInputStream(file), 8192));
    try {
        int x;
        while((x = dis.readInt()) != -1) { 
           int y = dis.readInt();
           double value = dis.readDouble();
           // store x,y, value in matrix
        } 
    } finally {
       dis.close();
    }

, как правильно указал Райан Амос, в случае, если матрица не разрежена, может быть быстрее просто записать значения (но все они):

Out:

    dos.write(xSize);
    dos.write(ySize);
    for (int x=0; x<xSize; x++) {
        for (int y=0; y<ySize; y++) {
            value = matrix[x,y];
            dos.write(value);
        }
    }

В:

   int xSize = dis.readInt();
   int ySize = dis.readInt();
   for (int x=0; x<xSize; x++) {
        for (int y=0; y<ySize; y++) {
              double value = dis.readDouble();
              matrix[x,y] = value;
        }
   }

(учтите, я не скомпилировал это - так что, возможно, вам придется исправить некоторые вещи - это не в моей голове).

Без буферов вы будетечитать побайтово, что сделает его медленным.

Еще один комментарий - с таким огромным набором данных, вы должны рассмотреть возможность использования SparseMatrix и писать / читать только те элементы, которые не равны нулю (если у вас действительно так многозначительного элементантс).

Как написано в комментарии выше - если вы действительно хотите записывать / читать каждый элемент в матрице такого размера, то вы уже говорите о часах записи, а не секундах.

2 голосов
/ 26 июня 2011

У вас есть несколько вариантов хранения ваших данных.Вы можете попробовать просто указать в заголовке, какая ширина, и выбросить все в список с разделителем (например, '\n', '\t', ' ' и т. Д.).В противном случае вы можете использовать специальный ObjectOutputStream для хранения ваших данных.Будьте осторожны: это, вероятно, будет более неэффективным, чем ваше решение.Тем не менее, его будет проще использовать.

Кроме этого, вы можете делать все, что пожелаете.Я обычно использую FileWriter и просто пишу все свои данные в виде текста.Если вам нужна суперэффективность, FileOutputStream - это то, что вам нужно.

1 голос
/ 26 июня 2011

Если нет необходимости сохранять данные (т.е. сохранять их после завершения работы java-программы), было бы быстрее сохранить их в памяти в переменной Java.Существует множество типов, которые должны соответствовать вашим требованиям (hashmap, arraylist ...).Если вам нужно сохранить данные, чтобы использовать их в последующих программах, вы можете сохранить их в файле, используя стандартные методы чтения / записи файлов.Простой ASCII будет быстрее для чтения / записи, чем XML.Что касается целостности файлов, то это связано с ОС, поскольку, в конце концов, это будет файл в вашей локальной файловой системе.

1 голос
/ 26 июня 2011

Все зависит от того, как вы будете выводить его позже, или если вы также будете хранить его в базе данных или где-то еще. Если вы никогда не выводите или не сохраняете его где-либо еще, то текстовый файл будет работать.

1 голос
/ 26 июня 2011

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

...