Запись и чтение данных микса в файл

1

Я хочу писать и читать данные в файлах и из них, которые начинаются со слова (строки), а затем массива байтов, в файле. Мой файл настолько огромен, и его содержимое выглядит так:

book byte[] array1 
bench byte[] array2
......

......

Я ищу эффективный способ выполнения этой задачи, эффективен ли мой способ реализации? , так как я не знаком с Java-IO, мне нужна ваша помощь.

Следующий код - это то, что я использовал для написания строки в файле до сих пор,

FileWriter fileWritter = new FileWriter(fileName,true);
BufferedWriter bufferWritter = new BufferedWriter(fileWritter);
bufferWritter.write(key+" ");
byte[] compressPostings=compress.compress(postings);


FileOutputStream fos = new FileOutputStream(fileName);
fos.write(compressPostings);
fos.close();

bufferWritter.newLine();
bufferWritter.close();
fileWritter.close();

Мой второй вопрос: как я могу прочитать из этого файла?

  • 0
    как насчет String.getBytes ()
  • 0
    FileInputStream
Показать ещё 1 комментарий
Теги:
java-io

4 ответа

0
Лучший ответ

Ваш подход страдает двумя основными проблемами, так как это в основном сочетание текстового и двоичного файлов.

  1. если ваши массивы не имеют постоянной длины, вы не знаете, где заканчивается массив и
  2. если вы используете разделительный символ, например \n, это может происходить, естественно, в массиве байтов.

Теперь, конечно, вы можете кодировать массив байтов, например, в base64, но это кажется мне действительно неуравновешенным. К сожалению, вы не уточняете, как именно этот формат указан прямо сейчас, и можете ли вы его изменить.

Если возможно, я бы обошел все эти проблемы и разрешил Java Serialization с несколькими преобразованиями ваших данных в виде списка массивов, где четные индексы содержат имена и нечетные двоичные данные. Метод toString - это просто показать, что он работает, и вы можете также добавить функцию удобства getRow().

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class HybridFile implements Serializable
{
    private static final long serialVersionUID = 1L;
    private List<byte[]> data = new ArrayList<>();

    public void addRow(String s,byte[] a)
    {
        data.add(s.getBytes()); // add encoding if necessary
        data.add(a);
    }

    @Override public String toString()
    {
        StringBuilder sb = new StringBuilder();
        synchronized (data)
        {
            for(int i=0;i<data.size();i+=2)
            {
                sb.append(new String(data.get(i)));
                sb.append(Arrays.toString(data.get(i+1))+"\n");
            }
        }
        return sb.toString();
    }

    public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException
    {
        HybridFile hf = new HybridFile();
        hf.addRow("peter",new byte[] {1,2,3});
        hf.addRow("jaqueline",new byte[] {4,5,6});

        try(ObjectOutput output = 
                new ObjectOutputStream(
                        new BufferedOutputStream(new FileOutputStream("hybrid"))))
        {output.writeObject(hf);}

        ObjectInput input = new ObjectInputStream(new BufferedInputStream(new FileInputStream("hybrid")));
        HybridFile hf2 = (HybridFile)input.readObject();

        System.out.println(hf2);
    }
}

Вывод

peter[1, 2, 3]
jaqueline[4, 5, 6]
0

Обратитесь к этому примеру:

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.DoubleBuffer;
import java.nio.LongBuffer;
import java.nio.channels.FileChannel;
public class MainClass {
  public static void main(String[] args) {
    long[] primes = new long[] { 1, 2, 3, 5, 7 };
    File aFile = new File("C:/test/primes.txt");
    FileOutputStream outputFile = null;
    try {
      outputFile = new FileOutputStream(aFile);
    } catch (FileNotFoundException e) {
      e.printStackTrace(System.err);
    }
    FileChannel file = outputFile.getChannel();
    final int BUFFERSIZE = 100;
    ByteBuffer buf = ByteBuffer.allocate(BUFFERSIZE);
    DoubleBuffer doubleBuf = buf.asDoubleBuffer();
    buf.position(8);
    CharBuffer charBuf = buf.asCharBuffer();
    for (long prime : primes) {
      String primeStr = "prime = " + prime;
      doubleBuf.put(0, (double) primeStr.length());
      charBuf.put(primeStr);
      buf.position(2 * charBuf.position() + 8);
      LongBuffer longBuf = buf.asLongBuffer();
      longBuf.put(prime);
      buf.position(buf.position() + 8);
      buf.flip();
      try {
        file.write(buf);
      } catch (IOException e) {
        e.printStackTrace(System.err);
      }
      buf.clear();
      doubleBuf.clear();
      charBuf.clear();
    }
    try {
      System.out.println("File written is " + file.size() + "bytes.");
      outputFile.close();
    } catch (IOException e) {
      e.printStackTrace(System.err);
    }
  }
}
0

Поскольку вы собираетесь добавлять новую строку для каждого байтового массива, использовать методы readLine() в любом классе XXXXReader в Java было бы удобно. Он будет читаться по строкам, поэтому вам не нужно использовать read() или read (byte [] b). Конечно, read() или read (byte [] b) работает, но вам может потребоваться добавить дополнительную логику для обработки байтов, которые вы читаете из файла.

  • 0
    Есть ли способ разделить другую сущность без использования новой строки? Это правильный способ писать и читать?
  • 0
    Вы можете либо определить свой собственный протокол для хранения этих метаданных, либо просто создать очень простой формат, обеспечивающий конкретный формат, например, [четыре байта, чтобы указать, сколько полезной нагрузки будет следовать] [фактическая полезная нагрузка] [еще четыре байта, чтобы указать, сколько полезной нагрузки будет следующий] [фактическая полезная нагрузка] и т. д., поэтому вы можете получить размер полезной нагрузки, прочитав первые четыре байта.
0

Создайте экземпляр FileInputStream для вашего файла.

В этом классе объявлен следующий метод:

public int read(byte[] b) throws IOException

Используйте его и обрабатывайте прочитанные байты, как хотите. Если должна быть строка, преобразуйте эти байты в строку.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню