我从 .txt 文件中读取了这个:
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*" to-ports="*" />
</cross-domain-policy>
但是在阅读然后输出之后我得到了这个:
null<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*" to-ports="*" />
</cross-domain-policy>
null开头,就是这个方法:
public class Filer {
private static String str;
public static String read(String file) {
BufferedReader br = null;
try {
String sCurrentLine;
br = new BufferedReader(new FileReader(file));
while ((sCurrentLine = br.readLine()) != null) {
str += sCurrentLine;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null)br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
return str;
}
}
返回的字符串由 System.out.println
输出
我尝试通过 str.indexOf("null");
或 str.indexOf("\0");
检查该字符串,但我得到 - 1
关于如何解决这个问题有什么想法吗?
最佳答案
考虑循环的第一次迭代。 str
的值为空,sCurrentLine
的值为是"<?xml version="1.0"?>"
.
在字符串连接中,空引用被转换为“null”的字符串。例如:
String x = null;
String y = "a";
String z = x + y; // "nulla"
因此在您的第一次迭代中,当您执行时:
str += sCurrentLine;
str
的值将是 "null<?xml version="1.0"?>"
你可以只初始化str
至 ""
...但我不会。
无论如何它都应该是一个静态变量是没有理由的——你真的想保留旧值,即使再次调用该方法吗?那将是非常奇怪的。它应该是一个本地变量。
此外,您不应该在这样的循环中使用字符串连接 - 这在性能方面很糟糕,因为它需要不断复制旧数据。使用 StringBuilder
相反。
我也不会捕获这样的异常——你真的希望调用者不知道发生了什么错误吗?只需声明您的方法可以抛出 IOException
.
此外,我不会使用 FileReader
我自己——它让你无法控制用于读取文件的编码——它总是使用平台默认编码,这可能是不合适的。我会使用 FileInputStream
包裹在 InputStreamReader
中.然后您可以使用 try-with-resources
Java 7 中关闭 FileInputStream
的语句自动。
因此,经过所有这些更改后,您的代码将变成如下所示:
public static String read(String file) throws IOException {
StringBuilder builder = new StringBuilder();
try (InputStream input = new FileInputStream(file)) {
BufferedReader reader = new BufferedReader(
new InputStreamReader(input, "UTF-8"));
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
}
return builder.toString();
}
请注意,这会将多行文件转换为单行 文本 - 使用 builder.append("\n")
或者如果您想保留行数(但不关心行分隔符),则在循环中使用类似的东西。如果您想保留确切的行结尾,请不要使用 readLine
- 只需将字符读入缓冲区即可。
此外,请考虑使用第三方库,例如 Guava改为执行所有这些 - 例如,您可以使用 Files.toString()
.
关于java从文件中读取文本后,开始打印 "null",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18426607/