控制台读取输入
public class IO {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
char c;
do{
c=(char)br.read();
System.out.println(c);
}while (c!=‘q‘);
}
}
这是菜鸟教程上面的一个例子.
实现的功能是从控制台读取输入,只要不为q(quit),就把它输出出来,然后继续循环.
我们主要看下这一句.BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
从里往外逐渐展开.
-
System.in
文档给的声明和介绍是这样的.public static final InputStream in
The "standard" input stream. This stream is already open and ready to supply input data. Typically this stream corresponds to keyboard input or another input source specified by the host environment or user.
从声明可以看出它是System类的一个类变量.
介绍说它是标准输入流,随时准备提供输入数据.
通常这个流就是键盘或者其他系统或用户指定的输入源.
粗略地简单概括一下,可以把它看作是个提供键盘输入的类变量.
既然看到这,那就把System类也顺便看一下.public final class System extends Object
这是个层级非常高,直接继承自Object,不可继承的Java内置类.
The System class contains several useful class fields and methods. It cannot be instantiated. Among the facilities provided by the System class are standard input, standard output, and error output streams; access to externally defined properties and environment variables; a means of loading files and libraries; and a utility method for quickly copying a portion of an array.
System类包含了很多有用的类变量和方法.
它不能被实例化.
System类提供了标准输入输出,错误输出流;访问外部定义属性和环境变量;加载文件和库;快速拷贝一部分数组的工具.
这样就很详细地把System.io
的文档给过了一遍,日后再深入就得读源码看具体实现了,感觉没有什么必要就是.
继续往下看,System.io
的外层
-
InputStreamReader
public class InputStreamReader extends Reader
继承自Reader类的输入流Reader
An InputStreamReader is a bridge from byte streams to character streams: It reads bytes and decodes them into characters using a specified charset. The charset that it uses may be specified by name or may be given explicitly, or the platform‘s default charset may be accepted.
Each invocation of one of an InputStreamReader‘s read() methods may cause one or more bytes to be read from the underlying byte-input stream. To enable the efficient conversion of bytes to characters, more bytes may be read ahead from the underlying stream than are necessary to satisfy the current read operation.
For top efficiency, consider wrapping an InputStreamReader within a BufferedReader. For example:
BufferedReader in
= new BufferedReader(new InputStreamReader(System.in));
InputStreamReader是字节流到字符流的桥梁.
它读取字节,然后特定的字符集对其进行编码.
可以通过名称指定字符集,也可以使用平台默认的.
每次InputStreamReader的read()方法被调用,都会导致一个或多个相应输入字节流的字节被读取.
为了实现字节到字符的有效转换,可以从底层流中提前读取比满足当前读取操作所需的更多字节。
最有效的办法是,在InputStreamReader包裹一个BufferedReader.
这边我们可以猜测,BufferedReader的功能就是让里面的字节流提前缓存.
查文档确认看看.
-
BufferedReader
public class BufferedReader extends Reader
Reads text from a character-input stream, buffering characters so as to provide for the efficient reading of characters, arrays, and lines.
The buffer size may be specified, or the default size may be used. The default is large enough for most purposes.
In general, each read request made of a Reader causes a corresponding read request to be made of the underlying character or byte stream. It is therefore advisable to wrap a BufferedReader around any Reader whose read() operations may be costly, such as FileReaders and InputStreamReaders. For example,
BufferedReader in
= new BufferedReader(new FileReader("foo.in"));
will buffer the input from the specified file. Without buffering, each invocation of read() or readLine() could cause bytes to be read from the file, converted into characters, and then returned, which can be very inefficient.
Programs that use DataInputStreams for textual input can be localized by replacing each DataInputStream with an appropriate BufferedReader.
从字符输入流中读取文本,缓冲字符以便提供字符,数组,行的有效读取.
看来我们的猜测是对的.
后面内容有点多就不翻了,大致两点意思
-
可以指定缓存大小
-
不用
BufferedReader
每次调用read()方法需要在调用底层的read()方法,消耗大=>缓存可以提高效率 -
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
回到开始,现在看这句话就能读懂很多意思了.
先声明了一个BufferedReader br
,然后new了一个BufferedReader
对象给它.
这个Reader对象是标准输入(键盘输入),经过字节->字符流转化,再缓存后得到的.
从控制台读取字符串
public class IO {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str;
System.out.println();
do{
str = br.readLine();
System.out.println(str);
}while (!str.equals("quit"));
}
}
一样的例子,只是读取的类型从char
换成了String
,读取的方法从read()
换成了readLine()
控制台输出
和System.in.read()
一样,System类也有相对应的标准输出方法System.out.write(int byteval)
它会把参数的低八位写到输出流中.
不过这很少用,因为不方便,一般使用sout,souf
什么是流
看了上面的例子,应该对流有了一个形象的认识.
这边再展开介绍一下.
一个流就是一个数据序列.
输入流从源读取数据,输出流向目标写入数据,统称IO流.
它们也可按类型分为两大类:字符流和字节流
再按输入输出分为Reader/Writer(字符流),InputStream/OutputStream(字节流)
读写文件
public class IO {
public static void main(String[] args) throws IOException {
try {
byte bWriter[] = {72,69,76,76,79};
OutputStream os = new FileOutputStream("test.txt");
for(byte c:bWriter){
os.write(c);
}
os.close();
InputStream is = new FileInputStream("test.txt");
int size = is.available();
for(int i =0;i<size;i++){
System.out.print((char) is.read());
}
} catch (IOException e) {
System.out.println("Exception");
}
}
}
这是一个利用FileInputStream
和FileOutputStream
处理数据,再通过OutputStream
和InputStream
实例来读写文件的例子
由于它是二进制写入,所以当写入内容不是ASCII码中的字母部分,可能会出现乱码
这时候我们就要用下面的办法
package com.company;
import java.io.*;
public class IO {
public static void main(String[] args) throws IOException {
File f = new File("test.txt");
FileOutputStream fop = new FileOutputStream(f);
OutputStreamWriter writer = new OutputStreamWriter(fop,"UTF-8");
writer.append("华为手机,就是好~");
writer.append("\r\n");
writer.append("华为手机,就是美~");
writer.close();
fop.close();
FileInputStream fip = new FileInputStream(f);
InputStreamReader reader = new InputStreamReader(fip,"UTF-8");
StringBuffer sb = new StringBuffer();
while (reader.ready()){
sb.append((char) reader.read());
}
System.out.println(sb.toString());
reader.close();
fip.close();
}
}
通过设定好编码的OutputStreamWriter
和InputStreamReader
来解决乱码的问题
创建目录
public class IO {
public static void main(String[] args) {
String dirname = "/tmp/user/java/bin";
File d = new File(dirname);
d.mkdir();
}
}
File类中有两个方法可以用来创建文件夹:
- mkdir( )方法创建一个文件夹,成功则返回true,失败则返回false。失败表明File对象指定的路径已经存在,或者由于整个路径还不存在,该文件夹不能被创建。
- mkdirs()方法创建一个文件夹和它的所有父文件夹。
读取目录
一个目录其实就是一个 File 对象,它包含其他文件和文件夹。
如果创建一个 File 对象并且它是一个目录,那么调用 isDirectory() 方法会返回 true。
可以通过调用该对象上的 list() 方法,来提取它包含的文件和文件夹的列表。
下面展示的例子说明如何使用 list() 方法来检查一个文件夹中包含的内容:
public class IO {
public static void main(String[] args) {
String dirname = "/tmp";
File f = new File(dirname);
if (f.isDirectory()){
System.out.println("Dictionary "+dirname);
String s[] = f.list();
for (int i=0;i<s.length;i++){
File fi = new File(dirname+‘/‘+s[i]);
if(fi.isDirectory()){
System.out.println(s[i]+" is a dictionary");
}else {
System.out.println(s[i]+" is a file");
}
}
}else {
System.out.println(dirname+" is not a dictionary");
}
}
}
删除目录或文件
因为目录其实和文件一样都是File对象.
所以我们可以用java.io.File.delete()
方法删除目录或文件.