J2SE学习笔记3 — Java基本语法(6)基本输入输出

3.8 输入输出

3.8.1读取输入

1java.util.Scanner类与标准输入流System.in

Scanner类是一个可以使用正则表达式来解析基本类型和字符串的简单文本扫描器。

使用Scanner类的基本流程:

²  Scanner类定义在java.util包中,因此在程序顶部要添加:

import java.util.*

²  然后需要构造一个Scanner对象,并与标准输入流System.in关联:

Scanner in = new ScannerSystem.in);

也可与文件流关联,例如Scanner sc = new Scanner(new File("myNumbers"));

²  现在可以使用Scanner类的各种方法实现输入操作,例如:

System.out.print(“What is your input->”);

String  ainput = in.nextLine(); //输入一行

String  firststr = in.next(); //读取一个单词(以空白符作为分隔符)

int     num  = in.nextInt();//读取一个整数

double  adouble = in.nextDouble();//读取一个浮点数

 

²  Scanner类常用API

ScannerInputStream  in

构造方法:用给定的输入流(System.in|File|String等)创建一个Scanner对象。

String  nextLine()

读取输入的下一个内容。

String  next()

读取输入的下一个单词(以空格作为分隔符)

int      nextInt()

double  nextDouble()

读取并转换下一个表示整数或浮点数的字符序列

boolean  hasNext()

boolean  hasNextInt()

boolean  hasNextLong()

boolean  hasNextDouble()

检测输入中是否还有其他单词(整数、长整型、浮点型)

void close()

关闭此扫描器

 

1:模仿用户名密码输入shell

import java.util.Scanner;

public class SecondSample

{

       public static void main(String[] args)

       {

       Scanner sin=new Scanner(System.in);

             

              System.out.print("username:");

              String username=sin.nextLine();

             

              System.out.print("password:");

              String passwd=sin.nextLine();

             

       if(!username.equals("admin") || !passwd.equals("admin"))

              {

                     System.out.println("username or passwd has error!");

                     System.exit(-1);

              }

              System.out.print("please input your name:");

              String name=sin.nextLine();

             

              System.out.print("please input your age:");

              int age=sin.nextInt();

        sin.close();

       System.out.println("/nYour name is "+name+";Your age is "+age);

              System.out.println("Welcome!");

       }

}

2 从磁盘文件中获取输入
import java.util.Scanner;
import java.io.File;
public class SecondSample 
{
               public static void main(String[] args) 
               {
                  Scanner sin=null;
                  try
                  {
                                  sin=new Scanner(new File("test.txt"));
                  }
                  catch (Exception e)
                  {
                                  System.out.println("要读取的文件不存在或输入流异常");
                                  System.exit(-1);
                  }
                 
                  String buf=null;
                  while(sin.hasNextLine())
                     {
                      buf=sin.nextLine();
                          System.out.println(buf);
                   }
sin.close();
               }
}
 

²  Scanner的分隔符模式和正则表达式

Scanner 使用分隔符模式将其输入分解为标记,默认情况下该分隔符模式与空白匹配。然后可以使用不同的 next 方法将得到的标记转换为不同类型的值。

扫描器还可以使用不同于空白的分隔符。下面是从一个字符串读取若干项的例子:

     String input = "1 fish 2 fish red fish blue fish";

     Scanner s = new Scanner(input).useDelimiter("//s*fish//s*");

     System.out.println(s.nextInt());

     System.out.println(s.nextInt());

     System.out.println(s.next());

     System.out.println(s.next());

     s.close();

输出为:

     1

     2

     red

     blue

以下代码使用正则表达式同时解析所有的 4 个标记,并可以产生与上例相同的输出结果:

     String input = "1 fish 2 fish red fish blue fish";

     Scanner s = new Scanner(input);

     s.findInLine("(//d+) fish (//d+) fish (//w+) fish (//w+)");

     MatchResult result = s.match();

     for (int i=1; i<=result.groupCount(); i++)

         System.out.println(result.group(i));

     s.close();

 

正则表达式的元字符

元字符

描述

.

匹配任何单个字符。例如正则表达式r.t匹配这些字符串:ratrutr t,但是不匹配root

$

匹配行结束符。例如正则表达式weasel$ 能够匹配字符串"He's a weasel"的末尾
但是不能匹配字符串"They are a bunch of weasels."

^

匹配一行的开始。例如正则表达式^When in能够匹配字符串"When in the course of human events"的开始,但是不能匹配"What and When in the"

*

匹配0或多个正好在它之前的那个字符。例如正则表达式.*意味着能够匹配任意数量的任何字符。

/

这是引用符,用来将这里列出的这些元字符当作普通的字符来进行匹配。例如正则表达式/$被用来匹配美元符号,而不是行尾,类似的,正则表达式/.用来匹配点字符,而不是任何字符的通配符。

[ ]
[c1-c2]
[^c1-c2]

匹配括号中的任何一个字符。例如正则表达式r[aou]t匹配ratrotrut,但是不匹配ret。可以在括号中使用连字符-来指定字符的区间,例如正则表达式[0-9]可以匹配任何数字字符;还可以制定多个区间,例如正则表达式[A-Za-z]可以匹配任何大小写字母。另一个重要的用法是排除,要想匹配除了指定区间之外的字符——也就是所谓的补集——在左边的括号和第一个字符之间使用^字符,例如正则表达式[^269A-Z] 将匹配除了269和所有大写字母之外的任何字符。

/< />

匹配词(word)的开始(/<)和结束(/>)。例如正则表达式/<the/>能够匹配字符串"for the wise"中的"the",但是不能匹配字符串"otherwise"中的"the"。注意:这个元字符不是所有的软件都支持的。

/( /)

/( /) 之间的表达式定义为group),并且将匹配这个表达式的字符保存到一个临时区域(一个正则表达式中最多可以保存9个),它们可以用 /1 /9 的符号来引用。

|

将两个匹配条件进行逻辑Or)运算。例如正则表达式(him|her) 匹配"it belongs to him""it belongs to her",但是不能匹配"it belongs to them."。注意:这个元字符不是所有的软件都支持的。

+

匹配1或多个正好在它之前的那个字符。例如正则表达式9+匹配999999等。注意:这个元字符不是所有的软件都支持的。

?

匹配01个正好在它之前的那个字符。注意:这个元字符不是所有的软件都支持的。

{i}
{i,j}

匹配指定数目的字符,这些字符是在它之前的表达式定义的。例如正则表达式A[0-9]{3} 能够匹配字符"A"后面跟着正好3个数字字符的串,例如A123A348等,但是不匹配A1234。而正则表达式[0-9]{4,6} 匹配连续的任意4个、5个或者6个数字字符。注意:这个元字符不是所有的软件都支持的。

 
2java.io.Console类实现控制台输入
从上面这个模仿用户名密码输入shell的例子可以看出:因为输入是可见的,所以Scanner类不适用于从控制台读取密码。为了实现这个目的,JDK6引入了Console类(java.io.Console)来实现这个目的,例如:

Console  cons=System.console();

String   username = cons.readLine(“Username:”);

char[]    passwd = cons.readPassword(“Password:”);//不会回显输入字符

   密码采用字符数组而不是字符串,主要考虑安全性。在对密码进行处理之后,应该马上用一个填充值覆盖数组元素。

   采用Console对象处理输入不如采用Scanner方便,每次只能读取一行输入,而没有能够读取一个单词或一个数值的方法。

²  Console类常用API

static Console console()    ——java.lang.System  jdk1.0

如果有可能进行交互操作,就通过控制台窗口为交互的用户返回一个Console对象,否则返回null。对于任何一个通过控制台窗口启动的程序,都可以使用Console对象。否则,其可用性将与所使用的系统有关。例如Console cons=System.console()

static  char[ ]  readPasswordString promptObject…args)——java.io.Console  jdk6

static  String  readLine String promptObject…args

显示字符串pormpt并且读取用户输入,直到输入行结束。args参数可以用来提供输入格式。

 

3.8.2 标准输出

   与标准输入System.in需要借助Scanner类不同,System.out可以直接将内容输出到控制台上。

   最常用:System.out.println();System.out.print();System.out.printf();

   System.out.println()输出后自动换行;

   System.out.print()输出后不自动换行;

   System.out.printf()可用于格式化输出;

—格式化输出

Java SE5.0System.out.printf沿用了C语言的printf方法所采用的格式化输出。

1)控制输出的字符宽度和小数点后精度

例如:System.out.printf(“%8.2f”,x);

8个字符的宽度和小数点后两个字符的精度打印x

2)用于printf格式化的转换符

转换符

类型

举例

转换符

类型

举例

d

十进制整数

159

s

字符串

Hello

x

十六进制整数

8f

c

字符

H

o

八进制整数

237

b

布尔

True

f

定点浮点数

1.5

h

散列码

42628b2

e

指数浮点数

1.5e+02

tx

日期时间

 

g

通用浮点数

-

%

百分号

%

a

十六进制浮点数

0x1.fccdp4

n

与平台有关的行分隔符

例如:

语句

输出

描述

int xInt=128;

System.out.print("The value of xInt :");

System.out.println(xInt);

The value of xInt :128

 

System.out.printf("%d/n",xInt);

System.out.printf("%x/n",xInt);

System.out.printf("%o/n",xInt);

128

80

200

十进制

十六进制

八进制

float yFloat=23.343f;

System.out.printf("%f/n",yFloat); System.out.printf("%e/n",yFloat);

System.out.printf("%g/n",yFloat);

System.out.printf("%a/n",yFloat);

System.out.printf("%.2f%%/n",yFloat);

23.343000

2.334300e+01

23.3430

0x1.757ceep4

23.34%

定点浮点数

指数浮点数

通用浮点数

十六进制浮点数

百分号

String str="Hello";

char   ch='H';

System.out.printf("%s/n",str);

System.out.printf("%c/n",ch);

Hello

H

字符串

字符

也可以利用多个转换符控制输出,例如:

 System.out.printf(“Hello%s. Next yearyou’ll be %d/n”,nameage);

 

3)格式化输出的控制标志

  标志

目的

举例

+

打印正数和负数的符号

+3333.33

空格

在正数之前添加空格

|  3333.33|

0

数字前面补0

003333.33

-

左对齐

|3333.33  |

(

将负数括在括号内

(3333.33)

添加分组分隔符

3,333.33

#(对于f格式)

包含小数点

3,333

#(对于x0格式)

添加前缀0x0

0xcafe

$

给定被格式化的参数索引,例如%1$d%1$x将以十进制和十六进制格式打印第1个参数

159  9F

格式化前面说明的数值,例如%d%<x%1$d%1$x同一效果

159  9F

1:用控制标志格式化整型输出

语句

输出

描述

int  xInt=  1281

System.out.printf("%d/n",xInt);

System.out.printf("%+d/n",xInt);

1281

+1281

无控制标志

打印正负号

System.out.printf("% 8dend./n",xInt);

System.out.printf("%08dend./n",xInt);

System.out.printf("%-8dend./n",xInt);

1281end.

00001281end.

1281    end.

在正数之前添加空格

数字前面补零

左对齐

System.out.printf("%(d/n",xInt);

System.out.printf("%,d/n",xInt);

System.out.printf("%#x/n",xInt);

System.out.printf("%#o/n",xInt);     

1281

1,281

0x501

02401

将负数括在括号内

逗号分隔

添加十六进制前缀0x

添加八进制前缀0

System.out.printf("%1$d  %1$#x  %1$#o/n",xInt);

System.out.printf("%d  %<#x  %<#o",xInt);

1281  0x501  02401

1281  0x501  02401

指定格式化参数索引

格式化前一个数值

int  xInt = 1281

System.out.printf("%d/n",xInt);

System.out.printf("%+d/n",xInt);

-1281

-1281

无控制标志

打印正负号

System.out.printf("% 8dend./n",xInt);

System.out.printf("%08dend./n",xInt);

System.out.printf("%-8dend./n",xInt);

   -1281end.

-0001281end.

-1281   end.

在正数之前添加空格

数字前面补零

左对齐

System.out.printf("%(d/n",xInt);

System.out.printf("%,d/n",xInt);

System.out.printf("%#x/n",xInt);

System.out.printf("%#o/n",xInt);     

(1281)

-1,281

0xfffffaff

037777775377

将负数括在括号内

逗号分隔

添加十六进制前缀0x

添加八进制前缀0

System.out.printf("%1$d  %1$#x  %1$#o/n",xInt);

System.out.printf("%d  %<#x  %<#o",xInt);

-1281 0xfffffaff 037777775377

-1281 0xfffffaff 037777775377

指定格式化参数索引

格式化前一个数值

2:用控制标志格式化浮点输出

 

 

float xFloat=  3333.33f;

float yFloat= - 3333.33f;

System.out.printf("%f , %f/n",xFloat,yFloat);

3333.330078,-3333.330078

System.out.printf("%+f , %+f/n",xFloat,yFloat);

System.out.printf("%(f , %(f/n",xFloat,yFloat);

System.out.printf("%#f/n",yFloat);

+3333.330078,-3333.330078

3333.330078,(3333.330078)

-3333.330078

System.out.printf("%1$f  %2$#f  %2$,f/n",xFloat,yFloat);

3333.330078  -3333.330078  -3,333.330078

System.out.printf("%f  %f  %<,(.2f /n",xFloat,yFloat);

3333.330078  -3333.330078  (3,333.33)

注:参数索引值从1开始而不是从0开始。

4)格式化字符串转换

可以使用s转换符格式化任意的对象。对于任意实现了Formattable接口的对象都将调用formatTo方法;否则将调用toString方法,它可以将对象转换为字符串。

例如可以使用静态的String.format方法创建一个格式化的字符串,而不打印输出:

String  mesg = String.format(“Hello%s. Next yearyou’ll be %d”,nameage);

5printf方法中日期与时间的格式化选项

printf方法中日期与时间(java.util.Date)的格式化以t开始,以下表中任意字母结束的两个字母格式控制格式化输出,例如System.out.printf(%tc”,new Date() )
 
 
转换符
类型
举例
显示完整的日期和时间(常用)
c
完整的日期和时间
Mon Feb 09 18:0519 PST 2004
F
ISO 8601日期
2004-02-09
D
美国格式的日期(月//年)
02/09/2010
T
24小时时间
18:04:20 
r
12小时时间
04:20:22 pm
R
24小时时间没有秒
18:10
Y
4位数字的年(前面补0
2010
y
年的后两位数字(前面补0
09
C
年的前两位数字(前面补0
20
B
月的完整拼写
February
bh
月的缩写
Feb
m
两位数字的月(前面补0
02
d
两位数字的日(前面补0
09
e
两位数字的月(前面不补0
9
j
三位数的年中的日子(前面补0),在001366之间
068
星期
A
星期几的完整拼写
Monday
a
星期几的缩写
Mon
时间的小时
H
两位数字的小时(前面补0),在023之间
09
k
两位数字的小时(前面不补0),在023之间
9
I
两位数字的小时,在012之间
11
时间的分钟、秒、毫秒等
M
两位数字的分钟(前面补0
05
S
两位数字的秒(前面补0
18
L
三位数字的毫秒(前面补0
047
N
九位数字的毫微秒(前面补0
047000000
时区和上下午
P
上午或下午的大写标志
PM
p
上午或下午的小写标志
pm
z
GMT起,RFC822数字位移
+0800
Z
时区
CST
s
从格林威治时间1970-01-01 00:00:00起的秒数
1304649206
Q
从格林威治时间1970-01-01 00:00:00起的毫秒数
1304649206278
 
例子:
 
 

转换符

语句

Date dt=new Date();

输出

描述

c

F

D

T

r

R

System.out.printf("%tc/n",dt);

System.out.printf("%tF/n",dt);

System.out.printf("%tD/n",dt);

System.out.printf("%tT/n",dt);

System.out.printf("%tr/n",dt);

System.out.printf("%tR/n",dt);

星期五 五月 06 10:33:26 CST 2011

2011-05-06

05/06/11

10:33:26

10:33:26 上午

10:33

完整的日期和时间

ISO 8601日期

美国格式的日期(月//年)

24小时时间

12小时时间

24小时时间(没有秒)

Y

y

C

System.out.printf("%tY/n",dt);

System.out.printf("%ty/n",dt);

System.out.printf("%tC/n",dt);

2011

11

20

4位数字的年

年的后两位数字

年的前两位数字

B

b

m

System.out.printf("%tB/n",dt);

System.out.printf("%tb/n",dt);

System.out.printf("%tm/n",dt);

五月

五月

05

月的完整拼写

月的缩写

两位数字的月

d

e

j

System.out.printf("%td/n",dt);

System.out.printf("%te/n",dt);

System.out.printf("%tj/n",dt);

06

6

126

两位数字的日(前补0

两位数字的日(不补0

三位数的年中日子

A

a

System.out.printf("%tA/n",dt);

System.out.printf("%ta/n",dt);

星期五

星期五

星期的完整拼写

星期的缩写

H

k

I

System.out.printf("%tH/n",dt);

System.out.printf("%tk/n",dt);

System.out.printf("%tI/n",dt);

10 (前面补0

10  (前面不补0

10

两位数字的小时(0~23

两位数字的小时(0~23

两位数字的小时(0~12

M

S

L

N

System.out.printf("%tM/n",dt);

System.out.printf("%tS/n",dt);

System.out.printf("%tL/n",dt);

System.out.printf("%tN/n",dt);

33

26

278

278000000

两位数字的分钟(补0

两位数字的秒

三位数字的毫秒

九位数值的毫微秒

p

z

Z

s

Q

System.out.printf("%tp/n",dt);

System.out.printf("%tz/n",dt);

System.out.printf("%tZ/n",dt);

System.out.printf("%ts/n",dt);

System.out.printf("%tQ/n",dt);

上午

+0800

CST

1304649206

1304649206278

上下午的小写标志

GMTRFC822位移

时区

1970起的秒数

1970起的毫秒数

注:许多格式化规则是本地环境特有的。例如上例中的时区是CST,星期和上下午都是中文方式输出的。又例如在德国Monday会被格式化为Montag

 

另外,还可以采用一个格式化的字符串指出要被格式化的参数索引,索引必须紧跟在%后面,并以$终止。例如:

System.out.printf("%1$s  %2$tB  %2$te  %2$tY/n" , "Date:" , new Date()); 

System.out.printf("%s    %tB    %<te   %<tY/n",  "Date:" , new Date());

输出结果都是

Date: 五月 6 2011

总结:格式说明符的语法图

 

3.8.3 文件的输入与输出

1)读取文件

n  首先import java.util.Scanner;和import java.io.File

n  然后需要一个用java.io.File对象构造的java.util.Scanner对象,例如

Scanner in =new Scannernew File(“myfile.txt”));或

Scanner in =new Scannernew File(“c://mydirectory//myfile.txt”));

n  利用Scanner的方法对文件进行读取;

n  最后关闭FileScanner对象;

2)写入文件

n  首先import java.util.Scanner;和import java.io.File

n  构造一个java.io.PrintWriter对象,在构造器中只需要提供文件名。例如

PrintWriter out = new PrintWriter(“myfile.txt”);

n  使用out.print(),out.printf(),out.println()等方法写入文件。

注:如果用一个不存在的文件构造一个Scanner或者用一个不能被创建的文件名构造一个PrintWriter,那么就会发生异常,因此应加入try{}catch(){}异常处理或在main方法中用throws子句标记如public static void mainString[] argsthrows FileNotFoundException

²  PrintWriter常用API

PrintWriter  append (char  c)

PrintWriter  append (CharSequence csq)

PrintWriter  append (CharSequence csq  , int start ,  int end)

将指定的字符或字符序列添加到此writer

PrintWriter  format (Locale l ,  String format ,  Object... args)

PrintWriter  formatString formatobject… args

使用指定格式字符串和参数将一个格式化字符串写入此writer

void  print   ()系列

void  printf  ()系列

void  println ()系列

提供多种方法重载写入此writer

void  write(char[] buf)

 void  write(char[] buf, int off, int len)

 void  write(int c)

 void  write(String s)

 void  write(String s, int off, int len)

写入字符数组、 写入字符数组的某一部、写入单个字符、写入字符串、写入字符串的某一部分。

 void  flush()

          刷新该流的缓冲。

 void  close()

          关闭该流并释放与之关联的所有系统资源。

 boolean  checkError()

          如果流没有关闭,则刷新流且检查其错误状态。

protected  void  clearError()

          清除此流的错误状态。

 

3)常用构造方法

java.util.Scanner   jdk5.0

ScannerFile  f

构造一个从给定文件读取数据的Scanner

ScannerString data

构造一个从给定字符串读取数据的Scanner

java.io.PrintWriter  jdk1.1

PrintWriter(File  f)

构造一个将数据写入给定文件的PrintWriter

PrintWriterString  fileName

构造一个将数据写入文件的PrintWriter,文件名由参数指定。

 

例:将日期写入文件再从文件读出

import java.util.Scanner;

import java.io.PrintWriter;

import java.io.File;

import java.util.Date;

public class Test

{

       public static void main(String[] args)

       {

              String dir=System.getProperty("user.dir");

              System.out.println(dir);

              PrintWriter out;

              try{

               out=new PrintWriter(new File("Test.txt"));

              }catch(Exception e)

              {

                 System.out.println(e);

                out=null;

              }

        String tmp=String.format("%1$s %2$tB %2$te %2$tY","Today Date:",new Date());

              out.println(tmp);

              out.format("%tc",new Date());

              out.flush();

              Scanner in=null;

              try{

                 in=new Scanner(new File("Test.txt"));

              }catch(Exception e)

              {

                 System.out.println("File not find");

              }

              String tmpin;

              while(in.hasNextLine())

              {

                     tmpin=in.nextLine();

                     System.out.println(tmpin);

              }

       }

}

注:当指定一个相对文件名时,例如“myfile.txt”,“mydirectory/myfile.txt”或“../myfile.txt”,文件位于Java虚拟机启动路径的相对位置。如果在命令行方式下用java MyProg启动程序,启动路径就是命令解释器的当前路径。然后,如果使用集成开发环境,那么启动路径将由IDE控制。因此可以使用下面的调用方式找到路径位置:

  String dir=System.getProperty(“user.dir”);

如果觉得定位文件比较烦恼,则可以考虑使用绝对路径,如“c://mydirectory//myfile.txt

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值