- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个包裹在文件上的 BufferedReader,我想标记一个地方并稍后使用 reset() 返回到这个位置。我已经阅读了java api,它指出标记(readlimit),当读取太多字节时,重置将失败。所以我想我可以设置一个很大的限制。
但是如果我有代码
BufferedReader br=...;
br.mark(1024000); // large but not as large as file.
while(br.ready()){
//keep reading. to find some stuff.
}
//now the br.ready() is false
br.reset() // It will fail with mark invalid exception
我认为问题是当 br 到达文件末尾时,br 不再就绪,并且重置失败....我可以设法继续阅读直到倒数第二行并停止,但是我该怎么做?
我发现一个丑陋的解决方案是使用 PushbackReader,以保存我阅读的所有内容并在 while 循环后返回。我想知道是否有更好的解决方案。
最佳答案
我想你错过了 documentation of mark()明确指出的地方
Parameters:
readAheadLimit - Limit on the number of characters that may be read while still preserving the mark. After reading this many characters, attempting to reset the stream may fail.
所以如果你想完全读取流和 reset()
之后你需要调用 mark()
参数至少和其他一样大你的文件。
但作为 BufferedReader.html#mark(int) 的文档添加
A limit value larger than the size of the input buffer will cause a new buffer to be allocated whose size is no smaller than limit. Therefore large values should be used with care.
因此,如果内存是一个问题,请考虑是否可以合并搜索和其他处理步骤,或者在这两个步骤之间重新打开源代码。当然还有一种方法可以利用 FileChannel它能够自由搜索任何给定文件,但不会为您提供字符或字符串。
您也许可以利用此类的 getReadCharacters()
和 reopenAt(BigInteger)
(未正确测试 BufferedReader
的直接替换作用于文件):
import java.io.*;
import java.math.BigInteger;
import java.nio.charset.Charset;
/**
* Created by TheConstructor for http://stackoverflow.com/a/24620470/1266906.
*/
public class MarkableFileReader extends Reader {
/**
* Cached instance of {@link java.math.BigInteger} of value
* {@link Long#MAX_VALUE} (used in {@link #skip(java.math.BigInteger)})
*/
public static final BigInteger LONG_MAX_VALUE = BigInteger.valueOf(Long.MAX_VALUE);
/**
* Default value of {@link #reopenOnResetThreshold} (10 MiB)
*/
public static final int DEFAULT_REOPEN_ON_RESET_THRESHOLD = 10 * 1024 * 1024;
/**
* Initialize the line-reading-buffer to this size
*/
public static final int EXPECTED_LINE_LENGTH = 80;
private final File file;
private final Charset charset;
private BufferedReader reader;
private BigInteger readCharacters;
private BigInteger mark;
private boolean reopenOnReset;
private final int reopenOnResetThreshold;
private final BigInteger reopenOnResetThresholdBI;
/**
* {@link java.io.BufferedReader#readLine()} is implemented to skip the
* {@code '\n'} of an {@code "\r\n"} only with the next read. The same
* behaviour is implemented here.
*/
private boolean skipLf;
private boolean skipLfMark;
public MarkableFileReader(String fileName) throws FileNotFoundException {
this(fileName, null);
}
public MarkableFileReader(String fileName, Charset charset) throws FileNotFoundException {
this(fileName, charset, DEFAULT_REOPEN_ON_RESET_THRESHOLD);
}
public MarkableFileReader(String fileName, Charset charset, int reopenOnResetThreshold)
throws FileNotFoundException {
this(new File(fileName), charset, reopenOnResetThreshold);
}
public MarkableFileReader(File file) throws FileNotFoundException {
this(file, null, DEFAULT_REOPEN_ON_RESET_THRESHOLD);
}
public MarkableFileReader(File file, Charset charset, int reopenOnResetThreshold) throws FileNotFoundException {
super();
this.file = file;
this.charset = charset;
this.mark = null;
this.skipLfMark = false;
this.reopenOnReset = false;
this.reopenOnResetThreshold = Math.max(0, reopenOnResetThreshold);
this.reopenOnResetThresholdBI = BigInteger.valueOf(this.reopenOnResetThreshold);
initReader();
}
private void initReader() throws FileNotFoundException {
final FileInputStream fileInputStream = new FileInputStream(file);
final InputStreamReader inputStreamReader = (charset == null) ?
new InputStreamReader(fileInputStream) :
new InputStreamReader(fileInputStream, charset);
reader = new BufferedReader(inputStreamReader);
this.readCharacters = BigInteger.ZERO;
this.reopenOnReset = true;
this.skipLf = false;
}
private void incrementReadCharacters() {
this.readCharacters = this.readCharacters.add(BigInteger.ONE);
}
private void incrementReadCharacters(final long characters) {
if(characters != -1) {
this.readCharacters = this.readCharacters.add(BigInteger.valueOf(characters));
}
}
@Override
public int read() throws IOException {
synchronized (lock) {
final int read = reader.read();
if (read != -1) {
incrementReadCharacters();
}
if (skipLf && read == '\n') {
skipLf = false;
return read();
}
return read;
}
}
@Override
public int read(char[] cbuf, int off, int len) throws IOException {
synchronized (lock) {
if ((off < 0) || (len < 0) ||
((off + len) > cbuf.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
if(skipLf) {
int firstChar = read();
if (firstChar == -1) {
return 0;
}
cbuf[off] = (char) firstChar;
if (len > 1) {
final int read = reader.read(cbuf, off + 1, len - 1);
incrementReadCharacters(read);
return read + 1;
} else {
return 1;
}
} else {
final int read = reader.read(cbuf, off, len);
incrementReadCharacters(read);
return read;
}
}
}
/**
* Reads a line of text. A line is considered to be terminated by any one
* of a line feed ('\n'), a carriage return ('\r'), or a carriage return
* followed immediately by a linefeed.
* <p>Note: this is not directly proxied to
* {@link java.io.BufferedReader#readLine()} as we need to know how many
* characters compose the line-ending for {@link #getReadCharacters()} to
* return correct numbers</p>
*
* @return A String containing the contents of the line, not including
* any line-termination characters, or null if the end of the
* stream has been reached
* @throws IOException
* If an I/O error occurs
* @see java.nio.file.Files#readAllLines(java.nio.file.Path, java.nio.charset.Charset)
* @see java.io.BufferedReader#readLine()
*/
public String readLine() throws IOException {
synchronized (lock) {
final CharArrayWriter charArrayWriter = new CharArrayWriter(EXPECTED_LINE_LENGTH);
int lastRead = read();
if(lastRead == -1) {
return null;
}
while (lastRead != -1 && lastRead != '\r' && lastRead != '\n') {
charArrayWriter.write(lastRead);
lastRead = read();
}
if(lastRead == '\r') {
skipLf = true;
}
return charArrayWriter.toString();
}
}
@Override
public long skip(long n) throws IOException {
if (n < 0L) {
throw new IllegalArgumentException("skip value is negative");
}
if(n == 0L) {
return 0L;
}
synchronized (lock) {
if(skipLf) {
int read = read();
if (read == -1) {
return 0;
}
final long skip = reader.skip(n - 1);
incrementReadCharacters(skip);
return skip + 1;
} else {
final long skip = reader.skip(n);
incrementReadCharacters(skip);
return skip;
}
}
}
@Override
public boolean ready() throws IOException {
synchronized (lock) {
return reader.ready();
}
}
@Override
public boolean markSupported() {
return true;
}
@Override
public void mark(int readAheadLimit) throws IOException {
if(readAheadLimit < 0) {
throw new IllegalArgumentException("readAheadLimit needs to be 0 or greater");
}
synchronized (lock) {
mark = readCharacters;
skipLfMark = skipLf;
reopenOnReset = false;
if (reader.markSupported()) {
if (readAheadLimit >= reopenOnResetThreshold) {
reader.mark(reopenOnResetThreshold);
} else {
reader.mark(readAheadLimit);
}
}
}
}
@Override
public void reset() throws IOException {
synchronized (lock) {
if (mark == null) {
throw new IOException("call mark() first");
}
final BigInteger readSinceMark = readCharacters.subtract(mark);
if (reopenOnReset ||
readSinceMark.compareTo(reopenOnResetThresholdBI) >= 0 ||
!reader.markSupported()) {
if (!reopenAt(mark)) {
throw new IOException("reopening at position failed");
}
} else {
reader.reset();
readCharacters = mark;
}
skipLf = skipLfMark;
}
}
@Override
public void close() throws IOException {
synchronized (lock) {
reader.close();
}
}
public BigInteger getReadCharacters() {
synchronized (lock) {
return readCharacters;
}
}
public boolean reopenAt(final BigInteger position) throws IOException {
synchronized (lock) {
if (reader != null) {
reader.close();
}
initReader();
BigInteger skip = skip(position);
return skip.equals(position);
}
}
public BigInteger skip(final BigInteger n) throws IOException {
synchronized (lock) {
BigInteger remaining = n;
while (remaining.compareTo(BigInteger.ZERO) > 0) {
long skip = skip(remaining.min(LONG_MAX_VALUE).longValue());
remaining = remaining.subtract(BigInteger.valueOf(skip));
if (skip < 1) {
break;
}
}
return n.subtract(remaining);
}
}
}
关于java - 读取到文件末尾后 BufferedReader 重置失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24620030/
我正在更改链接网址以添加 www.site.com/index.html?s=234&dc=65828 我通过此代码得到的是:site.com/&dc=65828 var target="&dc=65
我在编译过程中收到错误: src/smtp.c:208:1: warning: control reaches end of non-void function [-Wreturn-type] 这是相
这是我的 bootstrap/html 代码: Put email 位置正确,但我希望输入字段的大小延伸到 div 末尾。谁能帮帮我? 最佳答案 只需按百分比指定宽度,如下所示
我正在尝试获取一个像这样的 json 对象: filters = {"filters": myArray}; 并将其附加到 URL 的末尾,使用: this.router.navigate([`/de
这个问题已经有答案了: Remove hash from url (5 个回答) 已关闭 10 年前。 我有一个网站,stepaheadresidents.com ,并且井号 (#) 会自动添加到 u
我有这个代码 $('container a').appendTo('.container'); dzedzdqdqdqzdqdzqdzqdqzdqd Forgot password
为了练习更多 Python 知识,我尝试了 pythonchallenge.com 上的挑战 简而言之,作为第一步,此挑战要求从末尾带有数字的 url 加载 html 页面。该页面包含一行文本,其中有
我对 FS2 很陌生,需要一些有关设计的帮助。我正在尝试设计一个流,它将从底层的 InputStream 中提取 block ,直到结束。这是我尝试过的: import java.io.{File,
我对 FS2 很陌生,需要一些有关设计的帮助。我正在尝试设计一个流,它将从底层的 InputStream 中提取 block ,直到结束。这是我尝试过的: import java.io.{File,
我正在编写一个 ajax 应用程序,并且在 php 脚本中有一个函数: public function expire_user() { $r=array("return"=>'OK');
我正在使用一个QListView,它包装了一个非常简单的列表模型。我想尝试实现类似于某些网页中看到的“无限滚动”的东西。 目前,模型通过最多添加 100 个项目的方法更新(它们取自外部 Web API
运行 cucumber 测试给我以下错误 end of file reached (EOFError) /usr/lib64/ruby/2.0.0/net/protocol.rb:153:in
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我想知道版本命名的具体作用是什么? 喜欢 jquery.js?ver=1.4.4 我的意思是如果我使用像这样的 cdn jquery/1.4.4/jquery.min.js?ver=1.4.4但是另一
" data-fancybox-group="gallery" title="">" alt="" /> 在此代码中 echo $prod['item_image_url'];打印存储在我的表中的图像
我目前使用 Wordpress 作为博客平台,但我想更改为使用 Jekyll 来生成静态页面。在 WordPress 上,我的 URL 使用以下格式: /年/月/日/标题 但我想将其重定向到 /年/月
根据docs这应该是不可能的 Regular expressions cannot be anchored to the beginning or end of a token 尽管如此,它似乎对我有
有没有办法创建 dijit 并将其附加到 div 的末尾?假设我有以下代码: Add Person 我在网上找到了以下代码,但这替换了我的“attendants”div: var personCo
我有这段代码: //execute post (the result will be something like {"result":1,"error":"","id":"4da775
我需要一些函数方面的帮助。 我想编写一个插入链表的函数。但不仅仅是中间,如果必须插入前端或末尾,它也必须起作用。 结构: typedef struct ranklist { i
我是一名优秀的程序员,十分优秀!