Я хочу писать и читать данные в файлах и из них, которые начинаются со слова (строки), а затем массива байтов, в файле. Мой файл настолько огромен, и его содержимое выглядит так:
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();
Мой второй вопрос: как я могу прочитать из этого файла?
Ваш подход страдает двумя основными проблемами, так как это в основном сочетание текстового и двоичного файлов.
Теперь, конечно, вы можете кодировать массив байтов, например, в 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]
Обратитесь к этому примеру:
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);
}
}
}
Поскольку вы собираетесь добавлять новую строку для каждого байтового массива, использовать методы readLine() в любом классе XXXXReader в Java было бы удобно. Он будет читаться по строкам, поэтому вам не нужно использовать read() или read (byte [] b). Конечно, read() или read (byte [] b) работает, но вам может потребоваться добавить дополнительную логику для обработки байтов, которые вы читаете из файла.
Создайте экземпляр FileInputStream для вашего файла.
В этом классе объявлен следующий метод:
public int read(byte[] b) throws IOException
Используйте его и обрабатывайте прочитанные байты, как хотите. Если должна быть строка, преобразуйте эти байты в строку.
String.getBytes ()