因此,每当我尝试在这个特定文本中使用此ArrayList时,我都会遇到此错误。所以这是问题代码:
public static String lines(int start, int end, InputStream is) {
try {
BufferedReader fileBR = new BufferedReader(new InputStreamReader(is));
List<String> lines = new ArrayList<String>();
String strLine;
StringBuilder tempSB = new StringBuilder();
while ((strLine = fileBR.readLine()) != null) {
lines.add(strLine);
}
for (int i = start - 1; i < end; i++) {
tempSB.append(lines.get(i));
tempSB.append("\n");
}
line = tempSB.toString();
} catch (IOException e) {
e.printStackTrace();
}
return line;
}
我不确定代码的效率如何,但是在我的程序中获得一些基本功能后,我将继续努力提高效率。问题是当我使用它时:
// Edit lines according to where the headerFile starts
public static String getHeaderArt() {
return lines(1, 21, headerFile);
}
// Change to get the introduction text from a file
public static String getIntroText() {
return lines(2, 17, storyFile);
}
public static String getStart() {
return lines(20, 27, storyFile);
}
由于某种原因,前两个代码有效,但第三个代码没有。我的故事情节文件有28行,所以我不确定它为什么不起作用。
堆栈追踪:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 19, Size: 0
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at com.hathorsrpg.DefaultText.lines(DefaultText.java:42)
at com.hathorsrpg.DefaultText.getStart(DefaultText.java:86)
at com.hathorsrpg.Main.intro(Main.java:23)
at com.hathorsrpg.Main.main(Main.java:87)
这是一个没有文本文件的SSCCE:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class SSCCE {
public static InputStream storyFile = SSCCE.class.getResourceAsStream("/resources/storytext.txt");
public static InputStream headerFile = SSCCE.class.getResourceAsStream("/resources/castle.txt");
public static String line;
public static String lines(int start, int end, InputStream is) {
try {
BufferedReader fileBR = new BufferedReader(new InputStreamReader(is));
List<String> lines = new ArrayList<String>();
String strLine;
StringBuilder tempSB = new StringBuilder();
while ((strLine = fileBR.readLine()) != null) {
lines.add(strLine);
}
for (int i = start - 1; i < end; i++) {
tempSB.append(lines.get(i));
tempSB.append("\n");
}
line = tempSB.toString();
} catch (IOException e) {
e.printStackTrace();
}
return line;
}
// Edit lines according to where the headerFile starts
public static String getHeaderArt() {
return lines(1, 21, headerFile);
}
// Change to get the introduction text from a file
public static String getIntroText() {
return lines(2, 17, storyFile);
}
public static String getStart() {
return lines(20, 27, storyFile);
}
}
感谢未来的帮助,我似乎无法弄清楚问题。如果你想要一些东西放在一个文本文件中,这里有一些东西:
答案 0 :(得分:2)
问题是您已尝试重复使用
public static InputStream storyFile
在getIntroText()
和getStart()
来电中。虽然通过的start
和end
参数与您BufferedReader
while ((strLine = fileBR.readLine()) != null) { // read completely
lines.add(strLine);
}
这意味着InputStream
已经用尽,在getStart()
中无法重复使用,因为此时fileBR.readLine()
将返回NULL
和
while ((strLine = fileBR.readLine()) != null) {
lines.add(strLine); // never gets executed
}
因此,List<String> lines
中的getStart()
对size() = 0
仍为空,但您的代码仍在继续并调用
for (int i = start - 1; i < end; i++) {
tempSB.append(lines.get(i)); // index = 20 - 1 = 19
tempSB.append("\n");
}
因此你得到了
java.lang.IndexOutOfBoundsException:Index:19,Size:0
答案 1 :(得分:1)
你的方法:
public static String getStart() {
return lines(20, 27, storyFile);
}
正在尝试获取指定文件的20到27行。但这是基于一个假设,即您的文件至少有27行,这可能是也可能不是。
如果您的文件只有15行,例如,尝试获取第20行将导致IndexOutOfBoundsException。
这个问题的解决方案是这样的:
public static String lines(int start, int end, InputStream is) {
try {
BufferedReader fileBR = new BufferedReader(new InputStreamReader(is));
List<String> lines = new ArrayList<String>();
String strLine;
StringBuilder tempSB = new StringBuilder();
while ((strLine = fileBR.readLine()) != null) {
lines.add(strLine);
}
int start = start <= lines.size - 1 ? start : lines.size - 1;
int end = end <= lines.size - 1 ? end : lines.size - 1;
for (int i = start; i < end; i++) {
tempSB.append(lines.get(i));
tempSB.append("\n");
}
line = tempSB.toString();
} catch (IOException e) {
e.printStackTrace();
}
return line;
}
这样,如果指定一个大于行数上限的开头或结尾,它将不返回任何内容。如果仅指定大于上限的结束索引,则它将从开始索引返回到文件末尾,而不会导致IndexOutOfBoundsException。
答案 2 :(得分:0)
我认为错误可以缩小到这个:
for (int i = start - 1; i < end; i++) {
tempSB.append(lines.get(i));
tempSB.append("\n");
}
此处,end
是参数。你从哪里获得价值?您应该检查边界,以便end
在lines.size()
之前使用lines.size()
不会超过int max = end > lines.size() ? lines.size() : end;
int max = start > lines.size() ? lines.size() : start;
。像这样:
15
如果实际大小为end
且20
上升到is.reset();
tempSB = new BufferedReader(new InputStreamReader(is));
,则当迭代继续到比列表边界更远的索引时,会弹出异常。相同的逻辑适用于start,但反过来。
此外,您的文件阅读存在问题。第二次尝试阅读时,它会耗尽。像这样重置您的阅读器,以便能够再次阅读:
{{1}}
另一方面,更好的方法是读取一次,保留数据并在整个应用程序中使用它。
答案 3 :(得分:0)
根本原因是您正在重复使用storyFile输入流。您的方法getIntroText()
将完全读取storyFile输入流中的所有数据,直到结束,并且流将为空。之后,当您拨打getStart()
时,由于正在使用相同的流,因此不再需要从流中读取数据,lines
列表将为空!!简单修复,定义另一个流并将其用于getStart()
..(有更有效的方法来执行此操作,但您提到您将使用它...)
答案 4 :(得分:0)
在堆栈中查看大小为0的信息。
我认为如果你尝试从同一个文件中读取两次,那么第二次将你的流清空。