java - 为什么这个局部变量在 Java 中等于 null?
问题描述
我的目标是拥有一个存储文件内容的字符串。我从字面上撕掉了从 W3 学校( https://www.w3schools.com/java/java_files_read.asp )读取文件的算法,并简单地改变了一些东西。
public class Fileparser {
public void fileParse(String filename) {
try {
File myObj = new File("C:\\Users\\(myname)\\Desktop\\" + filename);
Scanner myReader = new Scanner(myObj);
String output = "";
while (myReader.hasNextLine()) {
String data = myReader.nextLine();
output.concat(data);
}
myReader.close();
System.out.println(output);
} catch (FileNotFoundException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
}
}
当然,主要是我有一个 Fileparser 对象,它使用我桌面上的文件执行该方法,但它绝对没有打印任何内容。我不得不与 Java 搏斗,因为我不熟悉局部变量的范围。当我逐行连接输出时,为什么什么都不打印?
解决方案
因为output.concat()
没有向字符串output
中添加任何内容指向:那是不可能的;java中的字符串是不可变的,不能更改。
相反,concat()
构造一个新字符串,它是接收者和参数的连接,并返回对其的引用。像output = output.concat(data)
完成工作这样简单的事情,但请注意,像这样的连接是非常低效的。更好的:
try {
File myObj = new File("C:\\Users\\(myname)\\Desktop\\" + filename);
Scanner myReader = new Scanner(myObj);
StringBuilder output = new StringBuilder();
while (myReader.hasNextLine()) {
String data = myReader.nextLine();
output.append(data);
}
myReader.close();
System.out.println(output);
} catch (FileNotFoundException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
现在让我们修复你的错误/文体假通行证:
- 未能安全关闭资源。
- 未能指定字符集编码,使此代码依赖于操作系统(因此,这是一个错误,并且您无法测试 - 非常糟糕)
- 非常愚蠢的异常处理
private static final String HOMEDIR = "C:\\Users\\yourname\\Desktop\\";
public String fileParse(String filename) throws IOException {
try (var s = new Scanner(new File(HOMEDIR + filename, StandardCharsets.UTF_8));
StringBuilder out = new StringBuilder();
for (String line = s.nextLine(); line != null; line = s.nextLine()) {
out.append(line);
}
return line.toString();
}
一个名为的方法parseFile
显然应该声明为throws IOException
. 这是该方法应该做的事情所固有的。
然后再来一次,使用现代 API 和命名约定:
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
private static final Path HOME = Paths.get(System.getProperty("user.home"), "Desktop");
public String parseFile(String fileName) {
return Files.readString(HOME.resolve(fileName));
}
看看那是多么的短和漂亮。单线!
注意:“文件”中的方法使用 UTF_8 作为默认值,而不是使用无用的“平台默认值”的旧东西。
推荐阅读
- python - 在工作世界中,构造函数的全球标准是什么?
- reactjs - 错误:未定义无法解析模块流(React Native)
- openshift - OpenShift:查看应用程序日志所需的最小角色集是什么?
- javascript - 如何使用文件的完整路径而不是文件的密钥从 S3 中删除文件
- javascript - 如何使用 js 打印复选框表?
- office365 - 将文本输入添加到图库项目
- django-forms - Django 分组选择字段迭代
- javascript - 如何在我的 Angular 项目中设计包含播放列表的视频播放器?
- jenkins - 将用户名和密码传递给Dimensions-Jenkins 作业
- kubernetes - 如何从 POD 中的另一个容器获取 Envoy (istio-proxy) 容器的 CPU 使用率