我對Java語言和庫還是一個新手......我經常在Python中使用這種模式,並想知道我應該如何使用Java來實現這一模式。在Java中實現這種模式的最佳方式(裏面的Python示例)?
我需要逐行讀取一個巨大的文件行,用某種形式的XML標記(我生產的投入,所以我肯定不會有任何歧義)
我想裏面的一些迭代像下面的Python代碼的巨大文件的部分:
(使用收益率/ Python的迭代器模式...有沒有在Java中任何equivallent我真的很喜歡for item in my collection: yield something_about(many items)
?)
這將是最好的( java)的方式來實現這種行爲?
THX
第一編輯: BTW,我本來也有興趣列表和文件之間的相似映射使用文件和文件時可用從一個Python的點[Python列表,如果中當然,也可以使用Java =>回答:看到使用的傑夫 - 福斯特建議:Apache.IOUtils
def myAcc(instream, start, end):
acc = []
inside = False
for line in instream:
line = line.rstrip()
if line.startswith(start):
inside = True
if inside:
acc.append(line)
if line.startswith(end):
if acc:
yield acc
acc = []
inside = False
f = open("c:/test.acc.txt")
s = """<c>
<a>
this is a test
</a>
<b language="en" />
</c>
<c>
<a>
ceci est un test
</a>
<b language="fr" />
</c>
<c>
<a>
esta es una prueba
</a>
<b language="es" />
</c>"""
f = s.split("\n") # here mimic for a input file...
print "Reading block from <c> tag!"
for buf in myAcc(f, "<c>", "</c>"):
print buf # actually process this inner part... printing is for simplification
print "-" * 10
print "Reading block from <a> tag!"
for buf in myAcc(f, "<a>", "</a>"):
print buf # actually process this inner part...
print "-" * 10
OUTPUT:
Reading block from <c> tag!
['<c>', '<a>', 'this is a test', '</a>', '<b language="en" />', '</c>']
----------
['<c>', '<a>', 'ceci est un test', '</a>', '<b language="fr" />', '</c>']
----------
['<c>', '<a>', 'esta es una prueba', '</a>', '<b language="es" />', '</c>']
----------
Reading block from <a> tag!
['<a>', 'this is a test', '</a>']
----------
['<a>', 'ceci est un test', '</a>']
----------
['<a>', 'esta es una prueba', '</a>']
----------
所以直接通過下面的傑夫 - 福斯特的回答啓發,這裏是一個試圖解決我的煩惱,做這樣的事情比我的Python代碼:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
interface WorkerThing {
public void doSomething(List<String> acc);
}
class ThatReadsLargeFiles {
public void readAHugeFile(BufferedReader input, String start, String end, WorkerThing action) throws IOException {
// TODO write some code to read through the file and store it in line
List<String> acc = new ArrayList<String>();
String line;
Boolean inside = false;
while ((line = input.readLine()) != null) {
if (line.equals(start)) {
inside = true;
}
if (inside) {
acc.add(line);
}
if (line.equals(end)) {
if (acc != null && !acc.isEmpty()) { // well not sure if both are needed here...
// Here you are yielding control to something else
action.doSomething(acc);
//acc.clear(); // not sure how to empty/clear a list... maybe : List<String> acc = new ArrayList<String>(); is enough/faster?
acc = new ArrayList<String>(); // looks like this is the *right* way to go!
}
inside = false;
// ending
}
}
input.close();
}
}
public class YieldLikeTest {
public static void main(String[] args) throws IOException {
String path = "c:/test.acc.txt";
File myFile = new File(path);
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(myFile), "UTF8"));
//BufferedReader in = new BufferedReader(new FileReader(path, "utf8"));
new ThatReadsLargeFiles().readAHugeFile(in, "<a>", "</a>", new WorkerThing() {
public void doSomething(List<String> acc) {
System.out.println(acc.toString());
}
});
}
}
第二編輯:我太快接受這個答案,其實,我還是很懷念,並有一個誤區:我不知道如何獲得並保持acc
內容的痕跡在@最上層(不是匿名內部類)。因此,它可以調用用於別的東西比打印比方說實例化一個類,並做其他處理...產量允許這種用法,我不明白我怎麼能適應所提出的答案有這樣的行爲。對不起,我的Python使用/示例很簡單。
所以這裏是從傑夫 - 福斯特解釋得出,用於存儲ACC答案:
class betweenWorker implements WorkerThing {
private List<String> acc;
public void process(List<String> acc) {
this.acc = acc;
}
public List<String> getAcc() { return this.acc; }
}
我r讀縮小你以前無效的代碼。我希望我說得對。 (這就是爲什麼你應該使用空格,而不是縮進標籤,最重要的是,不要混合這兩個) –
謝謝!是的,當我在另一個文本編輯器中粘貼時,我錯過了這一點,只是爲了在此處插入空格來粘貼代碼,所以代碼可以看作是這樣。 – user1340802