Для эффективности с очень большими файлами (обычно в ситуациях журналов, где вы можете использовать хвост), вы вообще не хотите читать весь файл (даже если вы делаете это, не читая сразу весь файл в памяти). Однако , вам нужно как-то выработать смещение в строках, а не в символах. Одной из возможностей является чтение назад с помощью seek () char char, но это очень медленно. Вместо этого его лучше обрабатывать в больших блоках.
У меня есть функция утилиты, которую я написал некоторое время назад, чтобы читать файлы назад, которые можно использовать здесь.
import os, itertools
def rblocks(f, blocksize=4096):
"""Read file as series of blocks from end of file to start.
The data itself is in normal order, only the order of the blocks is reversed.
ie. "hello world" -> ["ld","wor", "lo ", "hel"]
Note that the file must be opened in binary mode.
"""
if 'b' not in f.mode.lower():
raise Exception("File must be opened using binary mode.")
size = os.stat(f.name).st_size
fullblocks, lastblock = divmod(size, blocksize)
# The first(end of file) block will be short, since this leaves
# the rest aligned on a blocksize boundary. This may be more
# efficient than having the last (first in file) block be short
f.seek(-lastblock,2)
yield f.read(lastblock)
for i in range(fullblocks-1,-1, -1):
f.seek(i * blocksize)
yield f.read(blocksize)
def tail(f, nlines):
buf = ''
result = []
for block in rblocks(f):
buf = block + buf
lines = buf.splitlines()
# Return all lines except the first (since may be partial)
if lines:
result.extend(lines[1:]) # First line may not be complete
if(len(result) >= nlines):
return result[-nlines:]
buf = lines[0]
return ([buf]+result)[-nlines:]
f=open('file_to_tail.txt','rb')
for line in tail(f, 20):
print line
[Edit ] Добавлена более конкретная версия (избегает необходимости обратного обращения дважды)
Сначала вы должны создать сущность для таблиц. мы предполагаем, что State является сущностью для tbl_state, а Country является сущностью для tbl_country.
Страна субъекта:
@Entity
@Table(name = "tbl_country")
public class Country {
private Integer countryId;
@Id
@Column(name="country_id")
public String getCountryId(){
return countryId;
}
}
Государственный субъект:
@Entity
@Table(name = "tbl_state")
public class State {
private Integer stateId;
private String stateName;
private Country country;
@Id
@Column(name="state_id")
public String getStateId(){
return stateId;
}
@Column(name="state_name")
public String getStateName(){
return stateName;
}
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="country_id")
public Country getCountry(){
return country;
}
}
Код критерия:
Criteria stateCriteria = session.createCriteria(State.class);
Criteria countryCriteria = stateCriteria.createCriteria("country");
stateCriteria.addOrder(Order.desc("stateName"));
stateCriteria.setFirstResult(pagesize * pagenum);
stateCriteria.setMaxResults(pagesize);
List results = stateCriteria.list();
для пользовательского результата, Вы должны создать класс dto. Например, StateDto:
public class StateDto {
private String stateName;
private String countryName;
public String getStateName() {
return stateName;
}
public void setStateName(String stateName) {
this.stateName = stateName;
}
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
}
Тогда ваш код критерия может быть таким, как показано ниже.
Criteria stateCriteria = session.createCriteria(State.class);
Criteria countryCriteria = stateCriteria.createCriteria("country");
stateCriteria.addOrder(Order.desc("stateName"));
stateCriteria.setFirstResult(pagesize * pagenum);
stateCriteria.setMaxResults(pagesize);
stateCriteria.setProjection(Projections.projectionList()
.add(Projections.property("stateName").as("stateName"))
.add(Projections.property("country.name").as("countryName")));
List<StateDto> results = stateCriteria.list();