为什么这个局部变量在java中等于null?

iaqfqrcu  于 2021-06-29  发布在  Java
关注(0)|答案(4)|浏览(470)

我的目标是拥有一个存储文件内容的字符串。我真的撕毁了从w3学校读取文件的算法(https://www.w3schools.com/java/java_files_read.asp)只是改变了一些事情。

  1. public class Fileparser {
  2. public void fileParse(String filename) {
  3. try {
  4. File myObj = new File("C:\\Users\\(myname)\\Desktop\\" + filename);
  5. Scanner myReader = new Scanner(myObj);
  6. String output = "";
  7. while (myReader.hasNextLine()) {
  8. String data = myReader.nextLine();
  9. output.concat(data);
  10. }
  11. myReader.close();
  12. System.out.println(output);
  13. } catch (FileNotFoundException e) {
  14. System.out.println("An error occurred.");
  15. e.printStackTrace();
  16. }
  17. }
  18. }

当然,我有一个fileparser对象,它对我桌面上的一个文件执行该方法,但它完全不打印任何内容。我不得不与java搏斗,因为我不熟悉局部变量的范围。当我逐行连接到输出时,为什么输出什么都不打印?

jdg4fx2g

jdg4fx2g1#

按如下所示更改程序,使其按您的需要工作。这里,string的行为是当您创建一个新对象时,它总是将这些对象保留在字符串池中,并返回一个新的对象,因此您需要指定给现有的string对象来连接所有string对象。
当有多个连接时,总是建议使用stringbuilder。

  1. public class Fileparser {
  2. public void fileParse(String filename) {
  3. try {
  4. File myObj = new File("C:\\Users\\(myname)\\Desktop\\" + filename);
  5. Scanner myReader = new Scanner(myObj);
  6. String output = "";
  7. while (myReader.hasNextLine()) {
  8. String data = myReader.nextLine();
  9. output= output.concat(data);
  10. }
  11. myReader.close();
  12. System.out.println(output);
  13. } catch (FileNotFoundException e) {
  14. System.out.println("An error occurred.");
  15. e.printStackTrace();
  16. }
  17. }

}

展开查看全部
koaltpgm

koaltpgm2#

因为 output.concat() 不会给字符串添加任何内容 output 是指:那是不可能的;java中的字符串是不可变的,不能更改。
相反, concat() 构造一个新字符串,该字符串是接收器和参数的串联,并返回对该字符串的引用。简单到 output = output.concat(data) 会完成任务,但请注意,这样的合并效率非常低。更好:

  1. try {
  2. File myObj = new File("C:\\Users\\(myname)\\Desktop\\" + filename);
  3. Scanner myReader = new Scanner(myObj);
  4. StringBuilder output = new StringBuilder();
  5. while (myReader.hasNextLine()) {
  6. String data = myReader.nextLine();
  7. output.append(data);
  8. }
  9. myReader.close();
  10. System.out.println(output);
  11. } catch (FileNotFoundException e) {
  12. System.out.println("An error occurred.");
  13. e.printStackTrace();
  14. }

现在让我们来修复你的虫子/枯草的假通行证:
无法安全关闭资源。
未能指定字符集编码,使此代码依赖于操作系统(因此,这是一个bug,而且是一个您无法测试的bug-非常糟糕)
非常愚蠢的异常处理

  1. private static final String HOMEDIR = "C:\\Users\\yourname\\Desktop\\";
  2. public String fileParse(String filename) throws IOException {
  3. try (var s = new Scanner(new File(HOMEDIR + filename, StandardCharsets.UTF_8));
  4. StringBuilder out = new StringBuilder();
  5. for (String line = s.nextLine(); line != null; line = s.nextLine()) {
  6. out.append(line);
  7. }
  8. return line.toString();
  9. }

一个名为 parseFile 显然应该宣布 throws IOException . 这是该方法的固有功能。
再来一次,使用现代api和命名约定:

  1. import java.nio.file.Files;
  2. import java.nio.file.Path;
  3. import java.nio.file.Paths;
  4. private static final Path HOME = Paths.get(System.getProperty("user.home"), "Desktop");
  5. public String parseFile(String fileName) {
  6. return Files.readString(HOME.resolve(fileName));
  7. }

你看那有多短多漂亮。一个班轮!
注意:'files'中的方法使用utf8作为默认值,而旧的方法使用无用的'platform default'。

展开查看全部
oogrdqng

oogrdqng3#

必须使用“concat”的返回值。
参考 .concat Java文档。它提供了以下内容:
示例:

  1. "cares".concat("s") returns "caress"
  2. "to".concat("get").concat("her") returns "together"

这不是一个无效的方法。它是一个返回连接字符串结果的方法。所以在这种情况下,你应该:

  1. while (myReader.hasNextLine()) {
  2. String data = myReader.nextLine();
  3. output=output.concat(data);
  4. }

虽然为了提高效率,我建议使用 StringBuilder ,因为您经常连接:

  1. StringBuilder str = new StringBuilder();
  2. while (myReader.hasNextLine()) {
  3. String data = myReader.nextLine();
  4. str.append(data);
  5. }
  6. myReader.close();
  7. System.out.println(str.toString());

或者最好是打印循环内的每一行,而不是打印循环外的每一行,这将(在大多数情况下)保持文件的原始格式:

  1. Scanner myReader = new Scanner(myObj);
  2. while (myReader.hasNextLine()) {
  3. String data = myReader.nextLine();
  4. System.out.println(data);
  5. }
  6. myReader.close();
展开查看全部
hmtdttj4

hmtdttj44#

而不是 concat ,你通常会写 += 要附加到字符串:

  1. output += data;

然而,两者 += 以及 concat (如另一个答案所示,一旦修复)在一个循环中是缓慢的。更有效的方法是使用 StringBuilder :

  1. final StringBuilder sb = new StringBuilder();
  2. while (myreader.hasNextLine()) {
  3. sb.append(myreader.readNextLine());
  4. }
  5. System.out.println(sb);
  6. // or:
  7. final String output = sb.toString();
  8. System.out.println(output);

但这里其实没有这个必要:直接打印行:

  1. while (myReader.hasNextLine()) {
  2. System.out.println(myReader.nextLine());
  3. }
展开查看全部

相关问题