首页 > 代码库 > java(十)IO流
java(十)IO流
例: 关于键盘录入
package day22;
import java.io.IOException;
import java.io.InputStream;
public class ReadKey {
/**
* 关于键盘录入。
*/
public static void main(String[] args) throws IOException {
//readKey();
readKey2();
}
public static void readKey() throws IOException {
/*
* 需求:读取一个键盘录入的数据,并打印出来。
* 键盘本身就是一个标准的输入设备,java对于这种输入设备都有对应的对象。
*/
InputStream in=System.in;
int ch=in.read(); //阻塞式方法。
System.out.println(ch); //这个流不需要关闭,关了就再也启动不了了。
//默认输入流和输出流不需要关闭。
}
private static void readKey2() throws IOException {
/*
* 获取用户键盘录入的数据并变成大写输出。
* 如果用户输入over,结束键盘录入。
*
* 思路:
* 1.因为键盘录入只读取一个字节,要判断是否是over,要先将读到的字节拼成字符串。
* 2.那就需要一个容器。StringBuilder比较合适。
* 3.在用户回车之前将录入的数据变成字符串判断即可。
*/
//1.创建容器
StringBuilder sb=new StringBuilder();
//2.获取键盘读取流
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))
break;
System.out.println(temp.toUpperCase());
sb.delete(0, sb.length()); //这句是清空,否则就会把上一次的数据和这一次的数据一块输出。
}
//将读取到的字节存储到StringBuilder中。
else
sb.append((char)ch);
}
}
}
上面代码一个一个读,然后自己还要考虑换行啥的太麻烦了,就想到了readline()方法,
可是那是字符流的方法,怎么办呢?
这就用到了字符流和字节流之间的转换。
package day22;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class TransStreamDemo {
/** 对ReadKey中readKey2()方法的简化。
* 转换流:InputStreamReader,字节流转向字符流的桥梁。
* 相反,OutputStreamWriter,是字符流转向字节流的桥梁。
* @throws IOException
*/
public static void main(String[] args) throws IOException {
/*
InputStream in=System.in;
InputStreamReader isr=new InputStreamReader(in);
BufferedReader bufr=new BufferedReader(isr);
String line=null;
while((line=bufr.readLine())!=null){
if("over".equals(line))
break;
System.out.println(line.toUpperCase());
}
*/
//这句话一定牢记,以后一提到键盘录入就写这句话。其实就是上面注释了的代码的前三句。
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();
}
/* 思考
* 1.需求:将键盘录入的数据写入到一个文件中。
* 还是上面的代码,只将System.out换成文件地址即可。
* 2.需求:将一个文本文件内容显示在控制台上。
* 同理,还是上面的代码,只将System.in换成文件地址就行。
* 3.需求:讲一个文件的内容复制到另一个文件中。
* 把上面的System.out和System.in都换成文件地址就行。
*/
}
}
转换流:
InputStreamReader,字节流转向字符流的桥梁。解码
OutputStreamWriter,是字符流转向字节流的桥梁。编码
流的操作规律:
之所以要弄清楚这个规律,是因为流对象太多,开发时不知道到底要用那个对象合适。
想要知道开发时用到那些对象,只要通过四个明确即可。
1.明确源和目的(汇)
源:InputStream Reader
目的:OutputStream Writer
2.明确数据是否是纯文本数据。
源:是:Reader 否:InputStream
目的:是:Writer 否:OutputStream
3.明确具体的设备。
硬盘:File
键盘:System.in 控制台:System.out
内存:数组
网络:Socket流
4.明确是否需要其他额外功能。
高效(缓冲区) 转换
需求1:复制一个文本文件。
步骤:1.明确源和目的。 都有
2.明确数据是否是纯文本数据。是
3.明确具体的设备。硬盘
FileReader fr=new FileReader("demo.txt");
FileWriter fw=new FileWriter("demo.txt");
4.明确是否需要其他额外功能。NO
需求2:读取键盘录入信息,并写入到一个文件中。
步骤:1.明确源和目的。 都有
2.明确数据是否是纯文本数据。是
3.明确具体的设备。源:键盘 目的:硬盘
InputStream in=System.in;
FileWriter fw=new FileWriter("demo.txt");
这样可以完成,但是麻烦。将读取的字节数据转换成字符串,再由字符流操作。
4.明确是否需要其他额外功能。
是,转换,字节流转成字符流。因为已经明确的源是reader,这样操作文本数据更便捷。
InputStreamReader isr=new InputStreamReader(System.in);
FileWriter fw=new FileWriter("demo.txt");
还要功能吗? 要 ,高效
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
FileWriter fw=new BufferedWriter(FileWriter("demo.txt"));
需求3:将文本文件数据显示在控制台上。
BufferedReader bufr=new BufferedReader(new FileReader("demo.txt"));
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));
需求4:将键盘录入的数据显示在控制台上
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));
需求5:将一个中文字符串数据"你好"按照指定的编码表"UTF-8"写入到一个文本文件中。
这题的重点在指定的编码表上。中文Windows的默认编码表是gbk。
需求中已经明确了编码表,所以就不能用FileWriter,因为它内部是使用默认的本地编码表。
只能使用其父类OutputStreamWriter。OutputStreamWriter接受一个字节输出流对象,既然是 操作文件,那么该对象应该是FileOutputStream。
package day22;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class TransStreamDemo2 {
/**
* 转换流的第二个功能:可以使用指定的编码表编码。FileWriter只能用默认编码表。
* @throws IOException
*/
public static void main(String[] args) throws IOException {
writeText_3();
readText(); //读也得用指定编码表解码,要不就是乱码。
}
public static void readText() throws IOException {
InputStreamReader isr=new InputStreamReader(new FileInputStream("u8_1.txt"),"UTF-8");
char[] buf=new char[10];
int len=isr.read(buf);
String str=new String(buf,0,len);
System.out.println(str);
isr.close();
}
public static void writeText_3() throws IOException{
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("u8_1.txt"),"UTF-8");
osw.write("你好");
osw.close();
//在属性里可以发现前面两个文件都是4个字节,而这个是6个字节。因为UTF-8编码表中一个汉字3个字节。
}
public static void writeText_2() throws IOException {
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("gbk_2.txt"),"GBK");
//FileWriter fw=new FileWriter("gbk_1.txt");
/*
* 这两句代码的功能是相同的。
* FileWriter:其实就是转换流指定了本机默认码表的体现。而且这个转换流的子类对象,可以方便操作文本文件。
* 简单说,操作文件的字节流+本机的默认码表。这是按照默认码表操作文件的便捷类。
* 如果操作文件需要明确具体的编码表,FileWriter就不行了,必须用转换流。
*/
osw.write("你好");
osw.close();
}
public static void writeText() throws IOException {
FileWriter fw=new FileWriter("gbk_1.txt");
fw.write("你好");
fw.close();
}
}
什么时候使用转换流呢?、
1.源或者目的对应的设备是字节流,但是操作的却是文本数据,可以使用转换作为桥梁,提高对文本的操作便捷。
2.一旦操作文本涉及到具体的指定编码表时,必须用转换流。
File类
用来将文件或者文件夹封装成对象。方便对文件与文件夹的属性信息进行操作。
File对象可以作为参数传递给流的构造函数。
package day22;
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.util.Date;
public class FileDemo {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
ConstructorDemo();
}
public static void ConstructorDemo() throws IOException {
//可以将一个已存在的,或者不存在的文件或者目录封装成File对象。
File file=new File("E:\\demo.txt");
File file2=new File("E:\\","demo.txt");
File file3=new File("E:"+File.separator+"demo.txt");
System.out.println(file3);
fileMethodDemo();
}
public static void fileMethodDemo() throws IOException {
/*
* File对象的常见方法
* 1.获取
* 1.1 获取文件名称
* 1.2 获取文件路径
* 1.3 获取文件大小
* 1.4 获取文件修改时间
*/
File f=new File("demo.txt");
String name=f.getName();
String abspath=f.getAbsolutePath(); //获取绝对路径
String path=f.getPath(); //获取相对路径
long length=f.length();
long time=f.lastModified();
Date date=new Date(time);
DateFormat dateFormat=DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG);
String str_time=dateFormat.format(date);
System.out.println("name"+":"+name);
System.out.println("abspath"+":"+abspath);
System.out.println("path"+":"+path);
System.out.println("length"+":"+length);
System.out.println("str_time"+":"+str_time);
/*
* 2.创建与删除
* boolean
*/
createAndDeleteFile();
}
public static void createAndDeleteFile() throws IOException {
File file=new File("file.txt");
/*
* 和输出流不一样,如果文件不存在,则创建,否则,不创建。
*/
boolean b=file.createNewFile();
System.out.println(b);
boolean b1=file.delete();
System.out.println(b1);
//文件夹的创建与删除。
File dir=new File("abc");
boolean b2=dir.mkdir();
System.out.println(b2);
isDemo();
}
/*
* 3.判断
*/
public static void isDemo(){
File f=new File("abc.txt");
boolean b=f.exists();
System.out.println(b);
//最好先判断是否存在。
System.out.println(f.isFile());
System.out.println(f.isDirectory());
renameToDemo();
}
/*
* 4.重命名
*/
public static void renameToDemo(){
File f1=new File("demo.txt");
File f2=new File("Abc.txt");
f2.renameTo(f1);
}
}
过滤器的演示:
package day22;
import java.io.File;
import java.io.FilenameFilter;
public class FilterByJava implements FilenameFilter {
//java文件过滤器
public boolean accept(File dir, String name) {
return name.endsWith(".java");
}
}
package day22;
import java.io.File;
import java.io.FilenameFilter;
public class SuffixFilter implements FilenameFilter {
//文件后缀名过滤器
private String suffix;
public SuffixFilter(String suffix){
super();
this.suffix=suffix;
}
public boolean accept(File dir, String name) {
return name.endsWith(suffix);
}
}
package day22;
import java.io.File;
import java.io.FileFilter;
public class FilterByHidden implements FileFilter {
//隐藏文件过滤器
public boolean accept(File pathname) {
return !pathname.isHidden();
}
}
package day22;
import java.io.File;
public class FileListDemo {
/**
* @param args
*/
public static void main(String[] args) {
listDemo_4();
}
public static void listDemo_4() {
File dir=new File("e:\\");
File[] files=dir.listFiles(new FilterByHidden()); //过滤掉隐藏文件
for(File file:files){
System.out.println(file);
}
}
public static void listDemo_3() { //这个比demo_2方便,传啥过滤啥
File dir=new File("e:\\");
String[] names=dir.list(new SuffixFilter(".java")); //如果想过滤.txt文件,直接在这传.txt就行,不用去修改过滤器,方便一些。
for(String name:names){
System.out.println(name);
}
}
public static void listDemo_2() {
File dir=new File("e:\\");
String[] names=dir.list(new FilterByJava()); //过滤掉非Java类型的文件
for(String name:names){
System.out.println(name);
}
}
public static void listDem() {
File file=new File("e:\\");
/*
* 获取当前目录下的文件以及文件夹的名称,包含隐藏文件。
* 调用List方法的File对象中封装的必须是目录,否则空指针异常。访问系统级目录也会空指针异常。
* 如果目录存在但是没有内容,会返回一个数组,但是长度为零。
*/
String[] names=file.list();
for(String name:names){
System.out.println(name);
}
}
}
本文出自 “12946849” 博客,请务必保留此出处http://12956849.blog.51cto.com/12946849/1934943
java(十)IO流