抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

文件IO系列

文件和文件夹都是用File代表

文件对象

创建一个文件对象

注意:不是创建文件

首先导入 File

1
import java.io.File;

使用绝对路径或者相对路径创建File对象

1
2
3
4
5
// 绝对路径
File f1 = new File("d:/LOLFolder"); //这是一个文件夹

// 相对路径, 相对于工作目录(项目目录)
File f2 = new File("LOL.exe"); //这是一个文件
1
2
// 把f1作为父目录创建文件对象
File f3 = new File(f1, "LOL.exe");

文件常用方法

1
File f = new File("d:/LOLFolder/skin/garen.ski");
  • 获取文件相关信息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
f.exists();		//判断文件是否存在

f.isDirectory(); //判断是否是文件夹

f.isFile(); //判断是否是文件

f.length(); //文件长度(单位字节bytes)

long time = f.lastModified(); //返回从1970-1-1 08:00:00 开始的秒数
Date d = new Date(time);


f.setLastModified(0); //设置文件修改时间为1970.1.1 08:00:00

  • 文件、文件夹操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
f.list();
// 以【字符串数组】的形式,返回当前文件夹下的所有文件(不包含子文件及子文件夹)

File[]fs = f.listFiles();
// 以【文件(后缀为Files)数组】的形式,返回当前文件夹下的所有文件(不包含子文件及子文件夹)

f.getParent();
// 以【字符串】形式返回文件所在文件夹

f.getParentFile();
// 以【文件】形式返回获取所在文件夹

f.mkdir();
// 创建文件夹,如果父文件夹skin不存在,创建就无效

f.mkdirs();
// 创建文件夹,如果父文件夹skin不存在,就会创建父文件夹

f.createNewFile();
// 创建一个空文件,如果父文件夹skin不存在,就会抛出异常

f.getParentFile().mkdirs();
// 所以创建一个空文件之前,通常都会创建父目录

f.listRoots();
// 列出所有的盘符c: d: e: 等等

f.delete();
// 刪除文件

f.deleteOnExit();
// JVM结束的时候,刪除文件,常用于临时文件的删除

什么是流

流(Stream)就是一系列的数据

当不同的介质之间有数据交互的时候,JAVA就使用流来实现。
数据源可以是文件数据库网络,甚至是其他的程序

比如读取文件的数据到程序中,站在程序的角度来看,就叫做输入流

(输入输出是针对Java虚拟机JVM而言的,流入JVM叫输入,反之叫输出)

  • 输入流:InputStream
  • 输出流:OutputStream

什么是流

文件输入流

java中通过 FileInputStream() 实现文件输入流。

如下代码,就建立了一个文件输入流,这个流可以用来把数据从硬盘的文件,读取到JVM(内存)。

目前代码只是建立了流,还没有开始读取,真正的读取在下个章节讲解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package stream;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class TestStream {

public static void main(String[] args) {
try {
File f = new File("d:/lol.txt");//创建文件对象

// 创建基于文件的输入流,即将文件对象放入流中
FileInputStream fis = new FileInputStream(f);
// 通过这个输入流,就可以把数据从硬盘,读取到Java的虚拟机中来,也就是读取到内存中

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}

文件输出流

FileOutputStream :通过这个输出流,就可以吧数据从java的虚拟机中写入硬盘

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package stream;
 
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
 
public class TestStream {
    public static void main(String[] args) {
        File f =new File("d:/lol.txt");
        try {
            FileOutputStream fos = new FileOutputStream(f);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
 
    }
}

字节流

字节流即:用于以字节的形式读取和写入数据

InputStream:字节输入流
OutputStream:字节输出流

ASCII码概念

所有的数据存放在计算机中都是以数字的形式存放的。 所以字母就需要转换为数字才能够存放

比如A就对应的数字65,a对应的数字97. 不同的字母和符号对应不同的数字,就是一张码表。

ASCII是这样的一种码表。 只包含简单的英文字母、符号、数字等。 不包含中文,德文,俄语等复杂的。

以字节流形式读取文件内容

InputStream是字节输入流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。

FileInputStream 是InputStream 子类,以 FileInputStream 为例进行文件读取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package IOlearning.stream;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class StreamTest {

public static void main(String[] args) {
try {

File f = new File("d:/javaTest.txt"); //文件javaTest.txt内容是abc...xyz

// 创建基于文件的输入流
FileInputStream fis = new FileInputStream(f);

// 创建字节数组,其长度就是文件的长度
byte[] all = new byte[(int) f.length()];

fis.read(all); // 以字节流的形式读取文件所有内容到 all

for (byte b : all) {
System.out.print(b + " ");
// 打印出来是97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
}

// 每次使用完流,都应该进行关闭
fis.close();

} catch (IOException e) {
e.printStackTrace();
}

}
}

以字节流的形式向文件写入数据

OutputStream 是字节输出流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。

FileOutputStream 是OutputStream子类,以FileOutputStream 为例向文件写出数据

: 若文件d:/lol2.txt不存在,写出操作会自动创建该文件。
但是如果是文件 d:/xyz/lol2.txt,而目录xyz又不存在,会抛出异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package stream;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class TestStream {

public static void main(String[] args) {
try {
// 准备文件javaTest2.txt, 其中的内容是空的
File f = new File("d:/javaTest2.txt");

// 准备长度是2的字节数组,用88,89初始化,其对应的字符分别是X,Y
byte data[] = { 88, 89 };

// 创建基于文件的输出流
FileOutputStream fos = new FileOutputStream(f);

fos.write(data);// 把数据写入到输出流,注意data是个数组

// 关闭输出流
fos.close();

} catch (IOException e) {
e.printStackTrace();
}

}
}

总结(利用流读取文件步骤)

4个操作步骤:

  • 创建文件对象

  • 将文件放入对应的流(输入、输出流)

  • 操作流(读取、写入)

  • 关闭流(close)

关闭流的方式

在try里关闭

1
2
3
4
5
6
7
8
9
10
11
12
13
try {

File f = new File("d:/javaTest.txt");
FileInputStream fis = new FileInputStream(f);
byte[] all = new byte[(int) f.length()];
fis.read(all);

//使用完流,进行关闭
fis.close();

} catch (IOException e) {
e.printStackTrace();
}

在try的作用域里关闭文件输入流,在前面的示例中都是使用这种方式,这样做有一个弊端
如果文件不存在,或者读取的时候出现问题而抛出异常,那么就不会执行这一行关闭流的代码,存在巨大的资源占用隐患。 不推荐使用

在finally里关闭

这是标准的关闭流的方式

  1. 首先把流的引用声明在try的外面,如果声明在try里面,其作用域无法抵达finally.

  2. 在finally关闭之前,要先判断该引用是否为空

  3. 关闭的时候,需要再一次进行try catch处理

这是标准的严谨的关闭流的方式,但是看上去很繁琐,所以写不重要的或者测试代码的时候,都会采用上面的有隐患的方式,因为不麻烦🤣

下面是标准方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package stream;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class TestStream {

public static void main(String[] args) {
File f = new File("d:/lol.txt");
FileInputStream fis = null; //在try外部声明

try {
fis = new FileInputStream(f);
byte[] all = new byte[(int) f.length()];
fis.read(all);
for (byte b : all) {
System.out.println(b);
}

} catch (IOException e) {
e.printStackTrace();
} finally {

// 在finally 里关闭流
if (null != fis)
try {

fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}
}

使用try()的方式

把流定义在try()里,当try、catch或者finally结束的时候,会自动关闭。注意区别在try里关闭

这种编写代码的方式叫做 try-with-resources, 这是从JDK7开始支持的技术。

所有的流,都实现了一个接口叫做 AutoCloseable,任何类实现了这个接口,都可以在try()中进行实例化。 并且在try, catch, finally结束的时候自动关闭,回收相关资源。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package stream;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class TestStream {

public static void main(String[] args) {
File f = new File("d:/lol.txt");

//把流定义在try()里,try,catch或者finally结束的时候,会自动关闭
try (FileInputStream fis = new FileInputStream(f)) {

byte[] all = new byte[(int) f.length()];
fis.read(all);
for (byte b : all) {
System.out.println(b);
}
} catch (IOException e) {
e.printStackTrace();
}

}
}

字符流

上面所讲的 InputStreamOutputStream 是字节流;

这里还有字符流,即专门用于以字符的形式读写数据:

  • Reader
  • Writer

用字符流读取文件

FileReader 是 Reader子类,以FileReader 为例进行文件读取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package stream;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class TestStream {

public static void main(String[] args) {

// 准备文件lol.txt其中的内容是AB
File f = new File("d:/lol.txt");

// 创建基于文件的Reader
try (FileReader fr = new FileReader(f)) {

// 创建字符数组,其长度就是文件的长度
char[] all = new char[(int) f.length()];

// 以字符流的形式读取文件所有内容
fr.read(all);

for (char b : all) {
// 打印出来是A B
System.out.println(b);
}
} catch (IOException e) {
e.printStackTrace();
}

}
}

用字符流把字符串写入文件

FileWriter 是Writer的子类,以FileWriter 为例把字符串写入到文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package stream;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class TestStream {

public static void main(String[] args) {
// 准备文件lol2.txt
File f = new File("d:/lol2.txt");
// 创建基于文件的Writer
try (FileWriter fr = new FileWriter(f)) {

// 以字符流的形式把数据写入到文件中
String data="abcdefg1234567890";
char[] cs = data.toCharArray();
fr.write(cs);

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}

中文问题

编码概念

ASCII 字符集只有256个字符,用 0-255 之间的数字来表示。包括大小写字母、数字以及少数特殊字符:如标点符号、货币符号等。

对于大多数拉丁语言来说,这些字符已经够用。

但是,许多亚洲和东方语言所用的字符远远不止256个字符。有些超过千个。

因此,为了突破 ASCII 码字符数的限制,试图用新的编码方法来针对超过256个字符的语言编写计算机程序

常见编码

工作后经常接触的编码方式有如下几种:

  • ISO-8859-1/ASCII: 数字和西欧字母
  • GBK/GB2312/BIG5: 中文
  • UNICODE: 统一码,万国码

其中

  • ISO-8859-1 包含 ASCII
  • GB2312 是简体中文,BIG5是繁体中文,GBK同时包含简体和繁体以及日文。
  • UNICODE 包括了所有的文字,无论中文,英文,藏文,法文,世界所有的文字都包含其中

UNICODE和UTF

虽然UNICODE可以存储所有字符,但如果完全按照UNICODE的方式来存储数据,就会有很大的浪费。因为1个Unicode字符就占用4 bytes

倘若一篇文章大部分都是英文字母,那么按照UNICODE的方式进行数据保存就会消耗很多空间

在这种情况下,就出现了UNICODE的各种减肥子编码, 比如UTF-8对数字和字母就使用一个字节,而对汉字就使用3个字节,从而达到了减肥还能保证健康的效果

UTF-8,UTF-16和UTF-32 针对不同类型的数据有不同的减肥效果,一般说来UTF-8是比较常用的方式

UTF-8,UTF-16和UTF-32 彼此的区别在此不作赘述,有兴趣的可以参考 unicode-百度百科

UTF-8编码方式:数字和字母用一个字节, 汉字用3个字节。

Java采用的是Unicode

写在.java源代码中的汉字,在执行之后,都会变成JVM中的字符。
而这些中文字符采用的编码方式,都是使用UNICODE.

例如: "中"字对应的UNICODE是4E2D,所以在内存中,实际保存的数据就是十六进制的0x4E2D, 也就是十进制的20013。

一个汉字使用不同编码方式的表现

以字符 为例,查看其在不同编码方式下的值是多少

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package stream;

import java.io.UnsupportedEncodingException;

public class TestStream {

public static void main(String[] args) {
String str = "中";
showCode(str);
}

private static void showCode(String str) {
String[] encodes = { "BIG5", "GBK", "GB2312", "UTF-8", "UTF-16", "UTF-32" };
for (String encode : encodes) {
showCode(str, encode);
}

}

private static void showCode(String str, String encode) {
try {
System.out.printf("字符: \"%s\" 的在编码方式%s下的十六进制值是%n", str, encode);
byte[] bs = str.getBytes(encode);

for (byte b : bs) {
int i = b&0xff;
System.out.print(Integer.toHexString(i) + "\t");
}
System.out.println();
System.out.println();
} catch (UnsupportedEncodingException e) {
System.out.printf("UnsupportedEncodingException: %s编码方式无法解析字符%s\n", encode, str);
}
}
}

image-20210210233822081

用FileInputStream 字节流正确读取中文

为了能够正确的读取中文内容

  1. 必须了解文本是以哪种编码方式保存字符的

  2. 使用字节流读取文本

  3. 使用对应的编码方式去识别这些数字,得到正确的字符。

如本例,一个文件中的内容是字符"中",编码方式是GBK,那么读出来的数据一定是D6D0。

再使用GBK编码方式识别D6D0,就能正确的得到字符

注: 在GBK的棋盘上找到的字后,JVM会自动找到在UNICODE这个棋盘上对应的数字,并且以UNICODE上的数字保存在内存中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package stream;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class TestStream {

public static void main(String[] args) {
File f = new File("d:\\project\\j2se\\src\\test.txt"); //该文件保存时的编码方式为GBK

try (FileInputStream fis = new FileInputStream(f);) {

byte[] all = new byte[(int) f.length()];

fis.read(all); //使用字节流读取文本

String str = new String(all,"GBK"); //解码,解码方式为GBK
System.out.println(str);
} catch (IOException e) {
e.printStackTrace();
}

}
}

用FileReader 字符流正确读取中文

FileReader得到的是字符,所以一定是已经把字节根据某种编码识别成为字符

而FileReader使用的编码方式是Charset.defaultCharset()的返回值,如果是中文的操作系统,就是GBK

FileReader是不能手动设置编码方式的,为了使用其他的编码方式,只能使用InputStreamReader来代替,像这样:

1
new InputStreamReader(new FileInputStream(f), Charset.forName("UTF-8")); 

缓存流

以介质是硬盘为例,字节流和字符流的弊端
在每一次读写的时候,都会访问硬盘。 如果读写的频率比较高的时候,其性能表现不佳。

为了解决以上弊端,采用缓存流。
缓存流在读取的时候,会一次性读较多的数据到缓存中,以后每一次的读取,都是在缓存中访问,直到缓存中的数据读取完毕,再到硬盘中读取。

就好比吃饭,不用缓存就是每吃一口都到锅里去铲用缓存就是先把饭盛到碗里,碗里的吃完了,再到锅里去铲。

缓存流在写入数据的时候,会先把数据写入到缓存区,直到缓存区达到一定的量,才把这些数据,一起写入到硬盘中去。按照这种操作模式,就不会像字节流,字符流那样每写一个字节都访问硬盘,从而减少了IO操作,提高速度。

使用缓存流读取数据

缓存字符输入流 BufferedReader 可以一次读取一行数据,但要注意,缓存流必须建立在一个存在的流的基础上

先准备好文件 d:/lol.txt,文件内容如下:

garen kill teemo
teemo revive after 1 minutes
teemo try to garen, but killed again

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package stream;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class TestStream {

public static void main(String[] args) {

File f = new File("d:/lol.txt");

try (
FileReader fr = new FileReader(f); // 创建文件字符流
BufferedReader br = new BufferedReader(fr); // 缓存流必须建立在一个存在的流的基础上
)
{
while (true) {
String line = br.readLine();// 一次读一行
if (line == null)
break;
System.out.println(line);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}

使用缓存流写入数据

之前FileOutputStreamFileWriter要写入一串数据时,必须将数据转换为数组,一次只能写入一个字符。

PrintWriter 缓存字符输出流, 可以一次写入一行数据;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package stream;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class TestStream {

public static void main(String[] args) {
// 向文件lol2.txt中写入三行语句
File f = new File("d:/lol2.txt");

try (
FileWriter fw = new FileWriter(f); // 创建文件字符流
PrintWriter pw = new PrintWriter(fw); // 缓存流必须建立在一个存在的流的基础上

) {
pw.println("garen kill teemo"); //写入一行数据
pw.println("teemo revive after 1 minutes");
pw.println("teemo try to garen, but killed again");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}

flush方法

有的时候,需要立即把数据写入到硬盘,而不是等缓存满了才写出去。 这时候就需要用到flush()方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package stream;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class TestStream {
public static void main(String[] args) {
//向文件lol2.txt中写入三行语句
File f =new File("d:/lol2.txt");

try(
FileWriter fr = new FileWriter(f); //创建文件字符流
PrintWriter pw = new PrintWriter(fr); //缓存流必须建立在一个存在的流的基础上
) {
pw.println("garen kill teemo");
pw.flush(); //强制把缓存中的数据写入硬盘,无论缓存是否已满
pw.println("teemo revive after 1 minutes");
pw.flush();
pw.println("teemo try to garen, but killed again");
pw.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

数据流

  • DataInputStream 数据输入流
  • DataOutputStream 数据输出流

直接读写字符串

使用数据流的writeUTF()readUTF() 可以进行数据的格式化顺序读写
如本例,通过DataOutputStream 向文件顺序写出【布尔值,整数和字符串】。 然后再通过DataInputStream 顺序读入这些数据。

注: 要用DataInputStream 读取一个文件,这个文件必须是由DataOutputStream 写出的,否则会出现EOFException

因为DataOutputStream 在写出的时候会做一些特殊标记,只有DataInputStream 才能成功的读取。

读取步骤:

  1. 创建输入流 FileInputStream()
  2. 创建数据输入流 DataInputStream()
    • 读取布尔值:boolean b= dis.readBoolean();
    • 读取整数:int i = dis.readInt();
    • 读取字符串:String str = dis.readUTF();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
File f =new File("d:/lol.txt");
try (
FileInputStream fis = new FileInputStream(f);
DataInputStream dis =new DataInputStream(fis);
){
boolean b= dis.readBoolean();
int i = dis.readInt();
String str = dis.readUTF();

System.out.println("读取到布尔值:"+b);
System.out.println("读取到整数:"+i);
System.out.println("读取到字符串:"+str);

} catch (IOException e) {
e.printStackTrace();
}

写入步骤:

  1. 创建输出流:FileOutputStream()
  2. 创建数据输出流:DataOutputStream()
    • 写入布尔值true:dos.writeBoolean(true)
    • 写入整数:dos.writeInt(123)
    • 写入字符串:dos.writeUTF("This is my string")
1
2
3
4
5
6
7
8
9
10
11
File f =new File("d:/lol.txt");
try (
FileOutputStream fos = new FileOutputStream(f);
DataOutputStream dos =new DataOutputStream(fos);
){
dos.writeBoolean(true);
dos.writeInt(300);
dos.writeUTF("123 this is gareen");
} catch (IOException e) {
e.printStackTrace();
}

对象流

序列化一个对象

需要用到:

  • 对象输入流:ObjectInputStream
  • 对象输出流:ObjectOutputStream

把一个对象序列化有一个前提是:这个对象的类,必须实现了Serializable接口

1
2
3
4
5
6
7
8
9
10
11
package charactor;

import java.io.Serializable;

public class Hero implements Serializable {
//表示这个类当前的版本,如果有了变化,比如新设计了属性,就应该修改这个版本号
private static final long serialVersionUID = 1L;
public String name;
public float hp;

}

步骤:

  1. 创建一个Hero对象h,设置其名称为garen。
1
2
3
Hero h = new Hero();
h.name = "garen";
h.hp = 616;
  1. 把该对象序列化(即写入)到一个文件garen.lol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
File f =new File("d:/garen.lol");

try(
//创建对象输出流
FileOutputStream fos = new FileOutputStream(f);
ObjectOutputStream oos =new ObjectOutputStream(fos);

) {
oos.writeObject(h);

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
  1. 然后再通过序列化把该文件转换为一个Hero对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
File f =new File("d:/garen.lol");

try(
//创建对象输入流
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois =new ObjectInputStream(fis);
){
Hero h2 = (Hero) ois.readObject();
System.out.println(h2.name);
System.out.println(h2.hp);
}catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

System.in

  • System.out 是常用的在控制台输出数据的
  • System.in 可以从控制台输入数据
1
2
3
4
5
6
7
8
9
10
11
12
13
try (InputStream is = System.in;) {
while (true) {
// 敲入a,然后敲回车可以看到
// 97 13 10
// 97是a的ASCII码
// 13 10分别对应回车换行
int i = is.read();
System.out.println(i);
}
} catch (IOException e) {
e.printStackTrace();
}

Scanner读取字符串

使用System.in.read虽然可以读取数据,但是很不方便;
使用Scanner就可以逐行读取了

1
import java.util.Scanner;  //使用前需要导入
1
2
3
4
5
6
Scanner s = new Scanner(System.in);

while(true){
String line = s.nextLine();
System.out.println(line);
}

Scanner从控制台读取整数

1
2
3
4
5
Scanner s = new Scanner(System.in);
int a = s.nextInt();
System.out.println("第一个整数:" + a);
int b = s.nextInt();
System.out.println("第二个整数:" + b);

评论