一、键盘录入
1. 标准输入流和标准输出流
System.in:输入流。对应的标准输入设备,键盘。类型是InputStream。
System.out:输出流。对应的标准输出设备,控制台。类型是PrintStream。
2. 单字节录入与整行录入
单字节录入:当使用标准输入流读取键盘录入的数据时,只能一个字节一个字节的进行录入。
整行录入:为了提高键盘录入的效率,可以自定义一个数组存储每一行数据。当一行数据录入完后,整体操作这一行数据。这
个原理和字符流读取一行数据的原理一样,即readLine()方法。
<span style="font-size:18px">/*
* 例子:读取一个键盘录入的数据。并打印在控制台上。
*
* 键盘本身就是一个标注呢输入设备。
* 对于Java而言,对于这种输入设备都有对应的对象。
*/
import java.io.IOException;
import java.io.InputStream;
public class ReadKey {
public static void main(String[] args) throws IOException {
//'\r','\n'的ASII值
// System.out.println((int)'\r');//13
// System.out.println((int)'\n');//10
// readKey();
readKey2();
}
//整行录入
public static void readKey2() throws IOException {
/*
* 获取用户键盘录入的数据。
* 并将数据变成大写显示在控制台上。
* 如果用户输入的是over,结束键盘录入。
*
* 思路:
* 1.键盘录入只读取一个字节。要判断是否是over,需要先将读取到的字节拼成字符串。
* 2.那就需要一个容器。StringBuilder
* 3。在用户回车之前,将录入的数据变成字符串,判断即可。
*/
//1.创建容器。
StringBuilder sb = new StringBuilder();
//获取键盘读取流。
InputStream in = System.in;
//3.定义变量记录读取到的字节,并循环获取。
int ch = 0;
while((ch=in.read())!=-1){
//在存储时要判断是否是换行标记,因为换行标记不需要存储,
if(ch=='\r')
continue;
if(ch=='\n'){
String temp = sb.toString();
if("over".equals(temp))
//如果输入的是over,结束。
break;
//将字符串变成大写输出。
System.out.println(temp.toUpperCase());
sb.delete(0, sb.length());
}
else{
//将读取到的字节存储到StringBuilder中。
sb.append((char)ch);
// System.out.println(ch);
}
}
}
/**一个字节一个字节读取
* @throws IOException
*/
public static void readKey() throws IOException {
InputStream in = System.in;
//说明:系统回车符是\r\n,读取时这两个字符也会被读取,ASII值为13,10
int ch = in.read();//阻塞式方法。遇到流末尾或者抛出异常之前,一直阻塞。
System.out.println(ch);
int ch1 = in.read();
System.out.println(ch1);
int ch2 = in.read();
System.out.println(ch2);
// in.close();//System.in流对象就只有一个,关闭后,不能读取。键盘录入。所以不需要关闭。
//这是系统默认输入设备。
//默认输入,输出设备都不需要关闭,
int ch3 = in.read();
System.out.println(ch3);
}
}
</span>
3. 能不能直接使用readLine方法来完成键盘的整行录入呢?
答:readLine方法是BufferedReader类中的方法,而键盘录入使用的是字节流InputStream中的方法。
如何将字节流转换成字符流,再使用字符流缓冲区的readLine方法,这是需要考虑的问题。
如果使用转换流,这个问题将迎刃而解。
二、转换流
1. 概述
转换流可以实现字节流和字符流之间的转换,是字符流和字节流之间的桥梁,方便了两者之间的操作。
2. 转换流
InputStreamReader:字节流转换为字符流,解码。
OutputStreamWriter:字符流转换为字节流,编码。
3. 转换流=字节流+编码表。
解释:System.in是字节流。读取文本时,需要分两次读取,而InputStreamReader是字符流,读取文本时一次读取就行了。但是
底层还是调用了字节流读取,只不过读取时将两次读取到的字节流和编码表对照,并返回字节对应的文本。
附常见编码表:
ASCII:美国标准信息交换码 用一个字节的7位可以表示。
ISO8859-1:拉丁码表,欧洲码表,用一个字节的8位表示。
GB2312:中国的中文编码表。
GBK:中国的中文编码表升级版,融合了更多的中文文字符号。
Unicode:国际编码表,融合了多种文字,所有文字都用两个字节来表示,java
语言中使用的就是Unicode编码。
UTF-8:最多用三个字节来表示一个字符。
4. 什么时候使用转换流?
1) 源或者目的对应的设备是字节流,但是操作的却是文本数据,可以使用转换流。方便操作。
2) 一旦操作文本涉及到指定的编码表,必须使用转换流。
5. 转换流使用步骤(以InputStreamReader为例):
①获取键盘键盘读取流
InputStream in = System. In;
②使用转换流将字节流转换为字符流
InputStreamReader isr = newInputStreamReader(in);
③为了提高效率,可以使用字符流缓冲区
BufferedReader bdr = new BufferedReader(isr);
以上步骤的简写方式:BufferedReaderin=newBufferedReader(new InputStreamReader(System.in));
例子:需求:
获取用户键盘录入的数据,并将数据变成大写显示在控制台上。如果用户输入的是over,
结束键盘录入。
<span style="font-size:18px">import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
//转换流
public class TransStreamDemo2 {
public static void main(String[] args) throws IOException {
/*
// 字节流
InputStream in = System.in;
// 将字节流转换成字符流,转换流。这样才能调用字符流中的readLine()方法。
InputStreamReader isr = new InputStreamReader(in);
BufferedReader bufr = new BufferedReader(isr);
// 标准输出流。
OutputStream out = System.out;
// 字符流-->字节流
OutputStreamWriter osw = new OutputStreamWriter(out);
BufferedWriter bufw = new BufferedWriter(osw);
*/
// 简化形式
// 缓冲区(转换流(标准输入流))
BufferedReader bufr = new BufferedReader(new InputStreamReader(
System.in));
// 缓冲区(转换流(标准输出流))
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(
System.out));
String line = null;
while ((line = bufr.readLine()) != null) {
if ("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
}
}
</span>
三、流的操作规律
因为流对象太多,开发时不知道用哪个对象。所以就总结了流的操作规律。
流的操作规律:四个明确
1.明确源和目的
源:InputStream Reader
目的:OutputStream Writer
2.明确源和目的是否是纯文本数据。
源:是否是纯文本
是。 Reader
否。InputStream
目的:是否是纯文本?
是。Writer
否。OutputStream
3.明确具体的设备
源:
硬盘:File
键盘:System。in
内存:数组、
网络:Socket流
目的:
硬盘:File
控制台:System。out
内存:数组
网络:Socket流
4.明确是否需要额外的功能
1)是否需要需要高效(缓冲区)
是。加上Buffered
2)是否需要转换。
是。转换流。
需求1:复制一个文本文件。
1.明确源和目的
源:InputStream Reader
目的:OutputStream Writer
2.明确数据是否为纯文本数据。
源:
是纯文本。Reader
目的:
是纯文本。Writer
3.明确具体的设备
源:
硬盘:File
目的:
硬盘:File
FileReader fr = newFileReader("a.txt");
FileWriter fw = newFileWriter("b.txt");
4.是否需要额外功能
需要,需要高效。加上Buffered
BufferedReader bufr = newBufferedReader(new FileReader("a.txt");
BufferedWriter bufw = newBufferedWriter(new FileWriter("b.txt");
需求2:读取键盘录入的信息,并写入到文件中。
1.明确源和目的:
源:InputStream Reader
目的:OutputStream Writer
2.明确数据是否为纯文本数据。
是。
源:Reader
目的:Writer
3.明确具体设备:
源:
键盘:System。in
目的:
硬盘:File
InputStream fr = System.in;
FileWriter fw = new Writer("b.txt");
这样做可以完成,但是麻烦。将读取的字节数据专程字符串。
再由字符流操作。
4.是否需要额外功能。
需要,转换。将字节流专程字符流。因为明确的源是Reader,
这样操作文本数据最便捷。
所以要将已有的字节流专程字符流。使用字节-->字符 。 InputStreamReader
InputStreamReader isr = newInputStreamReader(System.in);
FileWriter fw = FileWriter("b.txt");
还需要额外功能么?
需要,高效。
BufferedReader bufr = newBufferedReader(new InputStreamReader(System.in);
BufferedWriter bufw = newBufferedWriter(new FileWriter("b.txt");
需求3:将一个文本文件数据显示在控制台上。
1.明确源和目的
源:InputStream Reader
目的:OutputStream Writer
2.明确数据是否是纯文本。
是。
源:Reader
目的:Writer
3.明确具体设备
源:
硬盘:File
目的:
控制台:System。out
FileReader fr = newFileReader("a.txt");
OutputStream out = System.out;//父类是PrintStream
4.需要额外功能么?
需要。转换。
FileReader fr = newFileReader("a.txt");
OutputStreamWriter osw = newOutputStreamWriter(System.out);
还需要高效。
BufferedReader bufr = new BufferedReader(new FileReader("a.txt");
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out);
需求4:读取键盘录入数据。显示在控制台上。
1.明确源和目的
源:InputStream Reader
目的:OutputStream Wirter
2.明确数据是否为纯文本。
是。
源:Reader
目的:Writer
3.明确具体设备
源:
键盘:System.in
目的:
控制台:System。out
InputStream in = System.in;
OutputStream out = System.out;
4.明确是否需要额外功能。
需要。转换。因为都是字节流,但是操作的却是文本数据,
所以使用字符流操作起来更为便捷。
InputStreamReader isr = new InputStreamReader(System.in);
OutputStreamWriter osw = new OutputStreamWriter(System.out);
为了将其高效操作,
BufferedReader bufr = newBufferedReader(new InputStreamReader(System.in);
BufferedWriter bufw = new BufferedWriter(newOutputStreamWriter(System.out);
需求5.将一个中文字符串数据按照指定的编码表写入到一个文本文件中。
1.目的:OutputStream Writer
2.是纯文本, Writer
3.设备:硬盘 File
FileWriter fw = newFileWriter("a.txt");
fw.write("你好");
注意:既然需求中明确了指定的编码表。就不能再使用FileWriter,因为FileWriter内部使用默认的本地码表,只能使用其父类OutputStreamWriter.
OutputStreamWriter接收一个字节流对象,既然是操作文件,那么对象应该是FileOutputStream。
OutputStreamWriter osw = newOutputStreamWriter(new FileOutputStream("a.txt"),charsetName);
若需要使用缓冲区,则
BufferedWriterbufw = new BufferedWriter(new OutputStreamWriter(newFileOutputStream("a.txt"),charsetName));
代码实现:
<span style="font-size:18px">//编码解码
/*
* 我们用的是默认的编码表。现在要按照指定的码表
*/
public class TransStreamDemo3 {
public static void main(String[] args) throws IOException {
// WriteText();
// WriteText_2();
// WriteText_3();
// readText_1();
readText_2();
}
public static void readText_2() throws IOException {
//如果GBK编码的文件按照utf-8编码表来解,会得出未知字符。
InputStreamReader isr = new InputStreamReader(new FileInputStream("gbk.txt"),"utf-8");
char[] buf = new char[10];
int len = isr.read(buf);
System.out.println(new String(buf,0,len));
isr.close();
}
public static void readText_1() throws IOException {
//解码时要按照对应的编码表来解码。
FileReader fr = new FileReader("u8.txt");
char[] buf = new char[10];
int len = fr.read(buf);
System.out.println(new String(buf,0,len));
fr.close();
}
public static void WriteText_3() throws IOException, FileNotFoundException {
//指定u8编码表,结果相同,但是文件大小不一样。u8编码表用3个字节来表示一个中文。
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("u8.txt"),"UTF-8");
osw.write("你好3");
osw.close();
}
public static void WriteText_2() throws IOException {
//转换流可以指定编码表。
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk_2.txt"),"GBK");
FileWriter fw = new FileWriter("gbk.txt");
/*
* 这两句代码的功能是等同的。
* FileWriter:其实就是转换流指定了本机默认码表的体现。而且这个转换流的子类对象,可以方便的操作文本文件。
* 简单说就是,操作文件的字节流+本机默认编码表。
* 这是按照默认码表来操作文件的便捷类。
*
* 如果操作文件需要明确具体的编码,FileWriter就不行了,必须用字节流。
*/
osw.write("你好2");
osw.close();
}
/**
* @throws IOException
*/
public static void WriteText() throws IOException {
//等效于OutputStreamWriter = new OutputStreamWriter(new FileOutputStream("gbk_2.txt"));
FileWriter fw = new FileWriter("gbk.txt");
fw.write("你好");
fw.close();
}
}
</span>
本文详细介绍了键盘录入的基本概念,包括单字节录入与整行录入的方法,并通过实例展示了如何使用转换流将字节流转换为字符流,进而实现高效、便捷的文本数据操作。
354

被折叠的 条评论
为什么被折叠?



