我正在编写一个函数来获取文本文件,并计算在将行输出到字符串数组时它有多少行。这样做我有几个例外我需要注意。类函数有几个变量,它们应该在整个函数中都有一个范围,但是当我在异常内部的函数中写入一个值时,return语句找不到它。我已经移动了声明,没有任何帮助
返回的值" h5Files" "可能尚未初始化"由于我不知道数组有多长,我无法将其初始化为一定长度。我在代码中执行此操作,我需要一种方法来告诉return语句我现在有一个值
这是代码
public String[] ReadScanlist(String fileIn){
int i;
String directory ="c:\\data\\"; // "\" is an illegal character
System.out.println(directory);
int linereader = 0;
String h5Files[];
File fileToRead = new File(directory + fileIn);
System.out.println(fileToRead);
try {
FileInputStream fin = new FileInputStream(fileToRead); // open this file
}
catch(FileNotFoundException exc) {
System.out.println("File Not Found");
}
try{
//read bytes until EOF is detected
do {
FileReader fr = new FileReader(fileToRead);// Need to convert to reader
LineNumberReader lineToRead = new LineNumberReader(fr); // Use line number reader class
//
while (lineToRead.readLine() != null){
linereader++;
}
linereader = 0;
lineToRead.setLineNumber(0); //reset line number
h5Files = new String[linereader];
while (lineToRead.readLine() != null){
h5Files[linereader] = lineToRead.readLine(); // deposit string into array
linereader++;
}
return h5Files;
}
while(i !=-1); // When i = -1 the end of the file has been reached
}
catch(IOException exc) {
System.out.println("Error reading file.");
}
try{
FileInputStream fin = new FileInputStream(fileToRead);
fin.close(); // close the file
}
catch(IOException exc) {
System.out.println("Error Closing File");
}
return h5Files;
}
答案 0 :(得分:0)
由于我不知道数组有多长,我无法初始化它 到一定的长度。
我认为阵列对你来说不是正确的解决方案 - 更不用说它无法完成,但你会重新发明轮子。
我建议您使用LinkedList,例如:
LinkedList<String> h5Files = new LinkedList<>();
h5Files.add(lineToRead.readLine());
或者你可以通过将数组设置为一个arbritary值(例如10)来重新发明轮子,然后在它变满时重新调整它的大小,如下所示:
h5Files = new String[10];
if (linereader = h5Files.size())
{
String[] temp = h5Files;
h5Files = new String[2 * linereader];
for (int i = 0; i < linereader; i++)
{
h5Files[i] = temp[i];
}
}
这些解决方案中的任何一个都允许您在try块之前在安全构造函数中初始化数组(或数组替代),以便在抛出任何异常时可以访问它
答案 1 :(得分:0)
这是你的问题。请用我的评论来查看代码的消化版本。
String h5Files[]; // here you define the variable. It still is not initialized.
try{
..................
do {
h5Files = new String[linereader]; // here you initialize the variable
} while(i !=-1); // When i = -1 the end of the file has been reached
..................
catch(IOException exc) {
// if you are here the variable is still not initialized
System.out.println("Error reading file.");
}
// you continue reading file even if exception was thrown while opening the file
我认为现在问题更清晰了。您尝试打开文件并计算行数。如果成功,则创建数组。如果不是(即抛出异常时),您捕获异常但仍继续读取该文件。但在这种情况下,您的数组未初始化。
现在该如何解决这个问题?
实际上,如果您第一次无法继续阅读文件。例如,如果文件不存在,则可能发生这种情况。因此,您应该在抛出第一个异常时返回,或者根本不捕获它。实际上,如果在任何阶段抛出异常,则与文件无关。异常不是返回代码。这就是存在例外的原因。
所以,根本不要捕捉异常。将您的方法声明为throws IOException
并删除所有try / catch块。
答案 2 :(得分:0)
你的代码非常奇怪。例如,这两个块没有任何意义:
try {
FileInputStream fin = new FileInputStream(fileToRead); // open this file
}
catch(FileNotFoundException exc) {
System.out.println("File Not Found");
}
try{
FileInputStream fin = new FileInputStream(fileToRead);
fin.close(); // close the file
}
catch(IOException exc) {
System.out.println("Error Closing File");
}
我不知道你认为他们做了什么,但除了第一个泄漏记忆外,他们什么都不做。这些评论更令人担忧,他们建议您需要在Java中更多地阅读IO。
删除这些块并整理代码a(移动声明,格式化)可以得到:
public String[] ReadScanlist(String fileIn) {
String directory = "c:\\data\\";
String h5Files[];
File fileToRead = new File(directory + fileIn);
try {
int i = 0;
do {
FileReader fr = new FileReader(fileToRead);
LineNumberReader lineToRead = new LineNumberReader(fr);
int linereader = 0;
while (lineToRead.readLine() != null) {
linereader++;
}
linereader = 0;
lineToRead.setLineNumber(0);
h5Files = new String[linereader];
while (lineToRead.readLine() != null) {
h5Files[linereader] = lineToRead.readLine();
linereader++;
}
return h5Files;
} while (i != -1);
} catch (IOException exc) {
System.out.println("Error reading file.");
}
return h5Files;
}
我的第一个争论焦点是File
相关代码。首先,File
从底层操作系统中抽象出来,因此使用/
绝对没问题。其次,File
有一个File
, String
构造函数是有原因的,这段代码应为:
File directory = new File("c:/data");
File fileToRead = new File(directory, fileIn);
但它确实应该使用新的Path
API(见下文)。
因此,您声明h5Files[]
。然后,您继续读取整个文件以计算行数。然后,将h5Files[]
分配给正确大小的数组。最后你填充数组。
如果在分配h5Files[]
之前任何地方 ,则表示您尚未对其进行初始化,因此无法将其返回。这就是编译器告诉你的。
我不知道此代码中i
做了什么,它在顶部分配给0
,然后从未重新分配。这是一个无限循环。
所以,你需要重新思考你的逻辑。如果你无法阅读该文件,我建议抛出IOException
。 从不 return null
- 这是一种反模式,会导致代码中的所有数千次null
次检查。如果您从未return null
,则永远不必检查它。
我可以建议以下替代代码:
如果您使用的是Java 7:
public String[] ReadScanlist(String fileIn) throws IOException {
final Path root = Paths.get("C:/data");
final List<String> lines = Files.readAllLines(root.resolve(fileIn), StandardCharsets.UTF_8);
return lines.toArray(new String[lines.size()]);
}
或者,如果你有Java 8:
public String[] ReadScanlist(String fileIn) throws IOException {
final Path root = Paths.get("C:/data");
try (final Stream<String> lines = Files.lines(root.resolve(fileIn), StandardCharsets.UTF_8)) {
return lines.toArray(String[]::new);
}
}