Java 在Producer范例中读取文本文件
在producer范例中有一个读取文本文件的任务。生产者接口定义如下:Java 在Producer范例中读取文本文件,java,io,producer-consumer,Java,Io,Producer Consumer,在producer范例中有一个读取文本文件的任务。生产者接口定义如下: public interface Producer<ITEM> { /** * Produces the next item. * * @return produced item */ ITEM next(); /** * Tells if there are more items available. * * @re
public interface Producer<ITEM> {
/**
* Produces the next item.
*
* @return produced item
*/
ITEM next();
/**
* Tells if there are more items available.
*
* @return true if there are more items, false otherwise
*/
boolean hasNext();
}
公共接口生成器{
/**
*生成下一项。
*
*@退回生产的物品
*/
下一项();
/**
*告知是否有更多可用项目。
*
*@如果有更多项目,则返回true,否则返回false
*/
布尔hasNext();
}
读取文本文件的当前代码为:
public static void readTextFile(File file, Charset charset, Consumer<String> consumer) {
try (InputStreamReader isr = new InputStreamReader(new FileInputStream(file), charset);
BufferedReader in = new BufferedReader(isr, BUFFER_SIZE)) {
String line;
while ((line = in.readLine()) != null) {
consumer.accept(line);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
publicstaticvoidreadtextfile(文件文件、字符集字符集、使用者){
try(InputStreamReader isr=newinputstreamreader(newfileinputstream(file),字符集);
BufferedReader in=新的BufferedReader(isr,缓冲区大小)){
弦线;
而((line=in.readLine())!=null){
消费者接受(行);
}
}捕获(IOE异常){
抛出新的运行时异常(e);
}
}
任务是将其转换为:
public static Producer<String> readTextFileRetProducer(File file, Charset charset) {
// ???
return null;
}
公共静态生产者readTextFileRetProducer(文件文件,字符集字符集){
// ???
返回null;
}
接下来是一系列问题:
public static Producer<String> readFile(File file, Charset charset) {
Stream<String> stream;
try {
stream = Files.lines(file.toPath(), charset);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
Iterator<String> iter = stream.iterator();
return new Producer<String>() {
@Override
public boolean hasNext() {
if (!iter.hasNext()) {
stream.close();
return false;
}
return true;
}
@Override
public String next() {
return iter.next();
}
};
}
publicstaticproducerreadfile(文件文件文件,字符集字符集){
溪流;
试一试{
stream=Files.lines(file.toPath(),charset);
}捕获(IOE异常){
抛出新的未选中异常(e);
}
迭代器iter=stream.Iterator();
返回新制作人(){
@凌驾
公共布尔hasNext(){
如果(!iter.hasNext()){
stream.close();
返回false;
}
返回true;
}
@凌驾
公共字符串next(){
返回iter.next();
}
};
}
通常,对文件等资源拆分“hasNext”和“getNext”操作是不安全的,这些文件可以由多个编写器修改。您可以考虑在内存中读取整个文件,在列表中,然后使用列表迭代器来实现HasNeXT()和NEXT()方法。@亚历克斯对该方法有一个巨大的“否”,因为所讨论的文件相当大。总体任务是构建一个及时的管道,其中包含合理数量的缓存,以节省资源并使用它们仅保留可行的任务数据。@Alex此外,在hasNext方法中始终可以选择执行实际读取,并使用next仅返回实际数据。(就像java.sql.ResultSet一样)总体思路是明确的,但是这个实现不允许改变读取缓冲区大小(我相信它仍然存在)。