Java:如何读取文本文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2788080/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java: How to read a text file
提问by aks
I want to read a text file containing space separated values. Values are integers. How can I read it and put it in an array list?
我想读取一个包含空格分隔值的文本文件。值为整数。如何读取它并将其放入数组列表中?
Here is an example of contents of the text file:
以下是文本文件内容的示例:
1 62 4 55 5 6 77
I want to have it in an arraylist as [1, 62, 4, 55, 5, 6, 77]
. How can I do it in Java?
我想将它作为[1, 62, 4, 55, 5, 6, 77]
. 我怎样才能在 Java 中做到这一点?
采纳答案by BalusC
You can use Files#readAllLines()
to get all lines of a text file into a List<String>
.
您可以使用Files#readAllLines()
将文本文件的所有行放入List<String>
.
for (String line : Files.readAllLines(Paths.get("/path/to/file.txt"))) {
// ...
}
Tutorial: Basic I/O > File I/O > Reading, Writing and Creating text files
教程:基本 I/O > 文件 I/O > 读取、写入和创建文本文件
You can use String#split()
to split a String
in parts based on a regular expression.
您可以使用基于正则表达式String#split()
将 a 分成String
几部分。
for (String part : line.split("\s+")) {
// ...
}
Tutorial: Numbers and Strings > Strings > Manipulating Characters in a String
You can use Integer#valueOf()
to convert a String
into an Integer
.
您可以使用Integer#valueOf()
将 aString
转换为Integer
.
Integer i = Integer.valueOf(part);
Tutorial: Numbers and Strings > Strings > Converting between Numbers and Strings
You can use List#add()
to add an element to a List
.
您可以使用List#add()
将元素添加到List
.
numbers.add(i);
Tutorial: Interfaces > The List Interface
教程:接口 > 列表接口
So, in a nutshell (assuming that the file doesn't have empty lines nor trailing/leading whitespace).
因此,简而言之(假设文件没有空行,也没有尾随/前导空格)。
List<Integer> numbers = new ArrayList<>();
for (String line : Files.readAllLines(Paths.get("/path/to/file.txt"))) {
for (String part : line.split("\s+")) {
Integer i = Integer.valueOf(part);
numbers.add(i);
}
}
If you happen to be at Java 8 already, then you can even use Stream APIfor this, starting with Files#lines()
.
如果您碰巧已经使用 Java 8,那么您甚至可以为此使用Stream API,从Files#lines()
.
List<Integer> numbers = Files.lines(Paths.get("/path/to/test.txt"))
.map(line -> line.split("\s+")).flatMap(Arrays::stream)
.map(Integer::valueOf)
.collect(Collectors.toList());
Tutorial: Processing data with Java 8 streams
回答by tschaible
Java 1.5 introduced the Scannerclass for handling input from file and streams.
Java 1.5 引入了Scanner类来处理来自文件和流的输入。
It is used for getting integers from a file and would look something like this:
它用于从文件中获取整数,看起来像这样:
List<Integer> integers = new ArrayList<Integer>();
Scanner fileScanner = new Scanner(new File("c:\file.txt"));
while (fileScanner.hasNextInt()){
integers.add(fileScanner.nextInt());
}
Check the API though. There are many more options for dealing with different types of input sources, differing delimiters, and differing data types.
虽然检查API。处理不同类型的输入源、不同的分隔符和不同的数据类型有更多的选择。
回答by Eddinho
Look at this example, and try to do your own:
看看这个例子,并尝试做你自己的:
import java.io.*;
public class ReadFile {
public static void main(String[] args){
String string = "";
String file = "textFile.txt";
// Reading
try{
InputStream ips = new FileInputStream(file);
InputStreamReader ipsr = new InputStreamReader(ips);
BufferedReader br = new BufferedReader(ipsr);
String line;
while ((line = br.readLine()) != null){
System.out.println(line);
string += line + "\n";
}
br.close();
}
catch (Exception e){
System.out.println(e.toString());
}
// Writing
try {
FileWriter fw = new FileWriter (file);
BufferedWriter bw = new BufferedWriter (fw);
PrintWriter fileOut = new PrintWriter (bw);
fileOut.println (string+"\n test of read and write !!");
fileOut.close();
System.out.println("the file " + file + " is created!");
}
catch (Exception e){
System.out.println(e.toString());
}
}
}
回答by Jonik
Just for fun, here's what I'd probably do in a real project, where I'm already using all my favourite libraries (in this case Guava, formerly known as Google Collections).
只是为了好玩,下面是我在一个真实项目中可能会做的事情,我已经在使用所有我最喜欢的库(在这种情况下Guava,以前称为Google Collections)。
String text = Files.toString(new File("textfile.txt"), Charsets.UTF_8);
List<Integer> list = Lists.newArrayList();
for (String s : text.split("\s")) {
list.add(Integer.valueOf(s));
}
Benefit: Not much own code to maintain (contrast with e.g. this). Edit: Although it is worth noting that in this case tschaible's Scanner solutiondoesn't have any more code!
好处:不需要维护太多自己的代码(与例如this形成对比)。编辑:尽管值得注意的是,在这种情况下,tschaible 的 Scanner 解决方案没有更多代码!
Drawback: you obviously may not want to add new library dependencies just for this. (Then again, you'd be silly not to make use of Guava in your projects. ;-)
缺点:您显然可能不想为此添加新的库依赖项。(再说一次,不在项目中使用番石榴是愚蠢的。;-)
回答by Sajjad Khan
This example code shows you how to read file in Java.
此示例代码向您展示了如何在 Java 中读取文件。
import java.io.*;
/**
* This example code shows you how to read file in Java
*
* IN MY CASE RAILWAY IS MY TEXT FILE WHICH I WANT TO DISPLAY YOU CHANGE WITH YOUR OWN
*/
public class ReadFileExample
{
public static void main(String[] args)
{
System.out.println("Reading File from Java code");
//Name of the file
String fileName="RAILWAY.txt";
try{
//Create object of FileReader
FileReader inputFile = new FileReader(fileName);
//Instantiate the BufferedReader Class
BufferedReader bufferReader = new BufferedReader(inputFile);
//Variable to hold the one line data
String line;
// Read file line by line and print on the console
while ((line = bufferReader.readLine()) != null) {
System.out.println(line);
}
//Close the buffer reader
bufferReader.close();
}catch(Exception e){
System.out.println("Error while reading file line by line:" + e.getMessage());
}
}
}
回答by user2601995
Using Java 7 to read files with NIO.2
使用 Java 7 通过 NIO.2 读取文件
Import these packages:
导入这些包:
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
This is the process to read a file:
这是读取文件的过程:
Path file = Paths.get("C:\Java\file.txt");
if(Files.exists(file) && Files.isReadable(file)) {
try {
// File reader
BufferedReader reader = Files.newBufferedReader(file, Charset.defaultCharset());
String line;
// read each line
while((line = reader.readLine()) != null) {
System.out.println(line);
// tokenize each number
StringTokenizer tokenizer = new StringTokenizer(line, " ");
while (tokenizer.hasMoreElements()) {
// parse each integer in file
int element = Integer.parseInt(tokenizer.nextToken());
}
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
To read all lines of a file at once:
一次读取文件的所有行:
Path file = Paths.get("C:\Java\file.txt");
List<String> lines = Files.readAllLines(file, StandardCharsets.UTF_8);
回答by Chris
Use Apache Commons(IO and Lang) for simple/common things like this.
将Apache Commons(IO 和 Lang)用于此类简单/常见的事情。
Imports:
进口:
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.ArrayUtils;
Code:
代码:
String contents = FileUtils.readFileToString(new File("path/to/your/file.txt"));
String[] array = ArrayUtils.toArray(contents.split(" "));
Done.
完毕。
回答by chiastic-security
All the answers so far given involve reading the file line by line, taking the line in as a String
, and then processing the String
.
到目前为止给出的所有答案都涉及逐行读取文件,将行作为 a String
,然后处理String
.
There is no question that this is the easiest approach to understand, and if the file is fairly short (say, tens of thousands of lines), it'll also be acceptable in terms of efficiency. But if the file is long, it's a very inefficient way to do it, for two reasons:
毫无疑问,这是最容易理解的方法,如果文件相当短(例如,数万行),在效率方面也是可以接受的。但是如果文件很长,这是一种非常低效的方法,原因有二:
- Every character gets processed twice, once in constructing the
String
, and once in processing it. - The garbage collector will not be your friend if there are lots of lines in the file. You're constructing a new
String
for each line, and then throwing it away when you move to the next line. The garbage collector will eventually have to dispose of all theseString
objects that you don't want any more. Someone's got to clean up after you.
- 每个字符都被处理两次,一次是在构造 中
String
,一次是在处理它。 - 如果文件中有很多行,垃圾收集器将不会成为您的朋友。您正在
String
为每一行构建一个新的,然后在移动到下一行时将其丢弃。垃圾收集器最终将不得不处理所有这些String
您不再需要的对象。总得有人来收拾你。
If you care about speed, you are much better off reading a block of data and then processing it byte by byte rather than line by line. Every time you come to the end of a number, you add it to the List
you're building.
如果您关心速度,那么最好读取一个数据块,然后逐字节而不是逐行处理它。每次到达数字的末尾时,都将其添加到List
正在构建的数字中。
It will come out something like this:
它会是这样的:
private List<Integer> readIntegers(File file) throws IOException {
List<Integer> result = new ArrayList<>();
RandomAccessFile raf = new RandomAccessFile(file, "r");
byte buf[] = new byte[16 * 1024];
final FileChannel ch = raf.getChannel();
int fileLength = (int) ch.size();
final MappedByteBuffer mb = ch.map(FileChannel.MapMode.READ_ONLY, 0,
fileLength);
int acc = 0;
while (mb.hasRemaining()) {
int len = Math.min(mb.remaining(), buf.length);
mb.get(buf, 0, len);
for (int i = 0; i < len; i++)
if ((buf[i] >= 48) && (buf[i] <= 57))
acc = acc * 10 + buf[i] - 48;
else {
result.add(acc);
acc = 0;
}
}
ch.close();
raf.close();
return result;
}
The code above assumes that this is ASCII (though it could be easily tweaked for other encodings), and that anything that isn't a digit (in particular, a space or a newline) represents a boundary between digits. It also assumes that the file ends with a non-digit (in practice, that the last line ends with a newline), though, again, it could be tweaked to deal with the case where it doesn't.
上面的代码假定这是 ASCII(尽管它可以很容易地针对其他编码进行调整),并且任何不是数字(特别是空格或换行符)的东西都代表数字之间的边界。它还假设文件以非数字结尾(实际上,最后一行以换行符结尾),但是,同样,可以对其进行调整以处理不是数字的情况。
It's much, much fasterthan any of the String
-based approaches also given as answers to this question. There is a detailed investigation of a very similar issue in this question. You'll see there that there's the possibility of improving it still further if you want to go down the multi-threaded line.
它比作为此问题的答案给出的任何基于 - 的方法都要快得多String
。在这个问题中有一个非常相似的问题的详细调查。你会看到,如果你想走多线程路线,还有可能进一步改进它。
回答by Ran Adler
read the file and then do whatever you want java8 Files.lines(Paths.get("c://lines.txt")).collect(Collectors.toList());
读取文件,然后做任何你想做的事情 java8 Files.lines(Paths.get("c://lines.txt")).collect(Collectors.toList());