GZIPInputStream чтение построчно
-
22-08-2019 - |
Вопрос
У меня есть файл в формате .gz.java-класс для чтения этого файла - GZIPInputStream.Однако этот класс не расширяет класс BufferedReader java.В результате я не могу прочитать файл построчно.Мне нужно что-то вроде этого
reader = new MyGZInputStream( some constructor of GZInputStream)
reader.readLine()...
Я подумываю о создании своего класса, который расширяет класс Reader или BufferedReader java и использует GZIPInputStream в качестве одной из его переменных.
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Reader;
import java.util.zip.GZIPInputStream;
public class MyGZFilReader extends Reader {
private GZIPInputStream gzipInputStream = null;
char[] buf = new char[1024];
@Override
public void close() throws IOException {
gzipInputStream.close();
}
public MyGZFilReader(String filename)
throws FileNotFoundException, IOException {
gzipInputStream = new GZIPInputStream(new FileInputStream(filename));
}
@Override
public int read(char[] cbuf, int off, int len) throws IOException {
// TODO Auto-generated method stub
return gzipInputStream.read((byte[])buf, off, len);
}
}
Но это не работает, когда я использую
BufferedReader in = new BufferedReader(
new MyGZFilReader("F:/gawiki-20090614-stub-meta-history.xml.gz"));
System.out.println(in.readLine());
Может кто - нибудь посоветовать , как поступить дальше ..
Решение
Базовая настройка декораторов выглядит следующим образом:
InputStream fileStream = new FileInputStream(filename);
InputStream gzipStream = new GZIPInputStream(fileStream);
Reader decoder = new InputStreamReader(gzipStream, encoding);
BufferedReader buffered = new BufferedReader(decoder);
Ключевой проблемой в этом фрагменте является ценность encoding
.Это кодировка символов текста в файле.Это "US-ASCII", "UTF-8", "SHIFT-JIS", "ISO-8859-9", ...?существуют сотни возможностей, и правильный выбор обычно не может быть определен из самого файла.Это должно быть указано через какой-то внеполосный канал.
Например, возможно, это платформа по умолчанию.Однако в сетевой среде это чрезвычайно хрупко.Машина, которая записала файл, может находиться в соседнем отсеке, но иметь другую кодировку файла по умолчанию.
Большинство сетевых протоколов используют заголовок или другие метаданные для явного указания кодировки символов.
В этом случае из расширения файла следует, что содержимое является XML.XML включает атрибут "encoding" в XML-объявление для этой цели.Кроме того, XML действительно должен обрабатываться с помощью синтаксического анализатора XML, а не как текст.Построчное чтение XML кажется хрупким частным случаем.
Неспособность явно указать кодировку является вопреки второй заповеди. Используйте кодировку по умолчанию на свой страх и риск!
Другие советы
GZIPInputStream gzip = new GZIPInputStream(new FileInputStream("F:/gawiki-20090614-stub-meta-history.xml.gz"));
BufferedReader br = new BufferedReader(new InputStreamReader(gzip));
br.readLine();
BufferedReader in = new BufferedReader(new InputStreamReader(
new GZIPInputStream(new FileInputStream("F:/gawiki-20090614-stub-meta-history.xml.gz"))));
String content;
while ((content = in.readLine()) != null)
System.out.println(content);
Вы можете использовать следующий метод в классе util и использовать его всякий раз, когда это необходимо...
public static List<String> readLinesFromGZ(String filePath) {
List<String> lines = new ArrayList<>();
File file = new File(filePath);
try (GZIPInputStream gzip = new GZIPInputStream(new FileInputStream(file));
BufferedReader br = new BufferedReader(new InputStreamReader(gzip));) {
String line = null;
while ((line = br.readLine()) != null) {
lines.add(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace(System.err);
} catch (IOException e) {
e.printStackTrace(System.err);
}
return lines;
}
вот с одной строкой
try (BufferedReader br = new BufferedReader(
new InputStreamReader(
new GZIPInputStream(
new FileInputStream(
"F:/gawiki-20090614-stub-meta-history.xml.gz")))))
{br.readLine();}