我可以使用 FileReader 来读取包含图像和视频(比如 epub 文件)和文本的文件吗?是否建议在性能方面这样做。
Can I use FileReader to read a file containing images and video (say an epub file) and text and is it suggested to do so with respect to perfomance.
我需要解析 epub 文件的内容,我正在尝试查看最有效的方法。 epub 文件可能包含图像、大量文本,偶尔也包含视频。我应该选择 FileInputStream 还是 FileReader?
以字节形式读取整个文件的最简单方法(如果它不是纯文本,这就是你想要的)是使用 java.nio.file.Files
class:
byte[] content = Files.readAllBytes(Paths.get("example.epub"));
这种方法的优点:
- 更少的代码 = 代码变得更易读并且出错的可能性更小
- java关心打开和关闭文件
编辑:
为了真正快速地读取文件,您也可以使用 java.nio
。这次java.nio.channels.FileChannel
:
import java.io.FileInputStream;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
// Load the file
FileChannel c = new FileInputStream("example.epub").getChannel();
MappedByteBuffer byteBuffer = c.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
// Process the data
buffer.get(myByte, 1120, 50);
// when finished
c.close();
这不会将整个文件读入内存,但会为文件创建一个 link 并仅读取(缓冲)您尝试访问的部分。它还会识别文件的更改,并始终 return 最新内容。
由于 epub 使用 ZIP 存档结构,我建议这样处理它。在下面找到一个小片段,其中列出了一个 epub 文件的内容。
Map<String, String> env = new HashMap<>();
env.put("create", "true");
Path path = Paths.get("foobar.epub");
URI uri = URI.create("jar:" + path.toUri());
FileSystem zipFs = FileSystems.newFileSystem(uri, env);
Path root = zipFs.getPath("/");
Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file,
BasicFileAttributes attrs) throws IOException {
print(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult preVisitDirectory(Path dir,
BasicFileAttributes attrs) throws IOException {
print(dir);
return FileVisitResult.CONTINUE;
}
private void print(Path file) throws IOException {
Date lastModifiedTime = new Date(Files.getLastModifiedTime(file).toMillis());
System.out.printf("%td.%<tm.%<tY %<tH:%<tM:%<tS %9d %s\n",
lastModifiedTime, Files.size(file), file);
}
});
示例输出
01.01.1970 00:59:59 0 /META-INF/
11.02.2015 16:33:44 244 /META-INF/container.xml
11.02.2015 16:33:44 3437 /logo.jpg
...
edit 如果您只想根据文件名提取文件,您可以按照 visitFile(...)
方法的代码片段所示进行操作。
public FileVisitResult visitFile(Path file,
BasicFileAttributes attrs) throws IOException {
// if the filename inside the epub end with "*logo.jpg"
if (file.endsWith("logo.jpg")) {
// extract the file in directory /tmp/
Files.copy(file, Paths.get("/tmp/",
file.getFileName().toString()));
}
return FileVisitResult.CONTINUE;
}
根据您希望如何处理 epub 中的文件,您还可以查看 ZipInputStream
。
try (ZipInputStream in = new ZipInputStream(new FileInputStream("foobar.epub"))) {
for (ZipEntry entry = in.getNextEntry(); entry != null;
entry = in.getNextEntry()) {
System.out.printf("%td.%<tm.%<tY %<tH:%<tM:%<tS %9d %s\n",
new Date(entry.getTime()), entry.getSize(), entry.getName());
if (entry.getName().endsWith("logo.jpg")) {
try (FileOutputStream out = new FileOutputStream(entry.getName())) {
// process the file
}
}
}
}
示例输出
11.02.2013 16:33:44 244 META-INF/container.xml
11.02.2013 16:33:44 3437 logo.jpg
我需要解析 epub 文件的内容,我正在尝试查看最有效的方法。 epub 文件可能包含图像、大量文本,偶尔也包含视频。我应该选择 FileInputStream 还是 FileReader?
以字节形式读取整个文件的最简单方法(如果它不是纯文本,这就是你想要的)是使用 java.nio.file.Files
class:
byte[] content = Files.readAllBytes(Paths.get("example.epub"));
这种方法的优点:
- 更少的代码 = 代码变得更易读并且出错的可能性更小
- java关心打开和关闭文件
编辑:
为了真正快速地读取文件,您也可以使用 java.nio
。这次java.nio.channels.FileChannel
:
import java.io.FileInputStream;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
// Load the file
FileChannel c = new FileInputStream("example.epub").getChannel();
MappedByteBuffer byteBuffer = c.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
// Process the data
buffer.get(myByte, 1120, 50);
// when finished
c.close();
这不会将整个文件读入内存,但会为文件创建一个 link 并仅读取(缓冲)您尝试访问的部分。它还会识别文件的更改,并始终 return 最新内容。
由于 epub 使用 ZIP 存档结构,我建议这样处理它。在下面找到一个小片段,其中列出了一个 epub 文件的内容。
Map<String, String> env = new HashMap<>();
env.put("create", "true");
Path path = Paths.get("foobar.epub");
URI uri = URI.create("jar:" + path.toUri());
FileSystem zipFs = FileSystems.newFileSystem(uri, env);
Path root = zipFs.getPath("/");
Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file,
BasicFileAttributes attrs) throws IOException {
print(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult preVisitDirectory(Path dir,
BasicFileAttributes attrs) throws IOException {
print(dir);
return FileVisitResult.CONTINUE;
}
private void print(Path file) throws IOException {
Date lastModifiedTime = new Date(Files.getLastModifiedTime(file).toMillis());
System.out.printf("%td.%<tm.%<tY %<tH:%<tM:%<tS %9d %s\n",
lastModifiedTime, Files.size(file), file);
}
});
示例输出
01.01.1970 00:59:59 0 /META-INF/
11.02.2015 16:33:44 244 /META-INF/container.xml
11.02.2015 16:33:44 3437 /logo.jpg
...
edit 如果您只想根据文件名提取文件,您可以按照 visitFile(...)
方法的代码片段所示进行操作。
public FileVisitResult visitFile(Path file,
BasicFileAttributes attrs) throws IOException {
// if the filename inside the epub end with "*logo.jpg"
if (file.endsWith("logo.jpg")) {
// extract the file in directory /tmp/
Files.copy(file, Paths.get("/tmp/",
file.getFileName().toString()));
}
return FileVisitResult.CONTINUE;
}
根据您希望如何处理 epub 中的文件,您还可以查看 ZipInputStream
。
try (ZipInputStream in = new ZipInputStream(new FileInputStream("foobar.epub"))) {
for (ZipEntry entry = in.getNextEntry(); entry != null;
entry = in.getNextEntry()) {
System.out.printf("%td.%<tm.%<tY %<tH:%<tM:%<tS %9d %s\n",
new Date(entry.getTime()), entry.getSize(), entry.getName());
if (entry.getName().endsWith("logo.jpg")) {
try (FileOutputStream out = new FileOutputStream(entry.getName())) {
// process the file
}
}
}
}
示例输出
11.02.2013 16:33:44 244 META-INF/container.xml
11.02.2013 16:33:44 3437 logo.jpg