文件IO操作
IO流用于处理设备之间的数据传输,JAVA对数据的操作是通过流的方式。
字符流和字节流
字节流有两个基类:
InputStream,OutputStream
字符流两个基类
Reader,Writer
示例一:
importjava.io.*;
class FileWriterDemo
{
public static void main(String[] args) throwsIOException
{
//创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件。
//而且该文件会被创建到指定目录下。如果该目录下已有同名文件,将被覆盖。
//其实该步骤就是在明确数据要存放的目的地。
FileWriter fw = new FileWriter("demo.text");
//调用Write方法,将字符串写入到流中
fw.write("abcde");
//刷新流对象中的缓冲中的数据;将数据刷到目的地中。
//fw.flush();
//关闭流资源,但关闭之前会刷新一次内部的缓冲中的数据。将数据刷到目的地中。
//和flush区别:flush刷新后,流可以继续使用,close刷新后,会将流关闭。
fw.close();
}
}
示例2:
importjava.io.*;
class FileWriterDemo2
{
public static void main(String[] args)
{
FileWriter fw = null;
try
{
fw = new FileWriter("demo.text");
fw.write("abcdefg");
}
catch (IOException e)
{
System.out.println(e.toString());
}
finally
{
try
{
if(fw!=null)
fw.close();
}
catch (IOException e)
{
System.out.println(e.toString());
}
}
}
}
演示3:文本文件读取方式(一)
importjava.io.*;
class FileWriterDemo3
{
public static void main(String[] args) throwsIOException
{
//传递一个true参数,代表不覆盖已有的文件。并在已有文件的末尾处进行数据续写。
FileWriter fw = new FileWriter("demo.text",true);
//换行\r\n
fw.write("您好!\r\n谢谢!");
fw.close();
}
}
示例4:
importjava.io.*;
class FileWriterDemo4
{
public static void main(String[] args) throwsIOException
{
//创建一个文件读取流对象,和指定名称的文件相关联。
//要保证该文件是已经存在的,如果不存在,会发生异常FileNotFoundException
FileReader fr = new FileReader("demo.text");
//调用读取流对象的read的方法
//read():一次读一个字符,而且会自动往下读。
int ch = 0;
while ((ch=fr.read())!=-1)
{
System.out.println((char)ch);
}
fr.close();
}
}
演示4:文本文件读取方式(二)
通过数组进行读取。
importjava.io.*;
class FileReaderDemo2
{
public static void main(String[] args) throwsIOException
{
FileReader fr = new FileReader("demo.text");
//定义一个字符数组,用于存储读到的字符。
//该read(char[])返回的是读到字符个数
char[] buf = new char[1024];
int num = 0;
while ((num=fr.read(buf))!=-1)
{
System.out.println(new String(buf,0,num));
}
fr.close();
}
}
演示5:
importjava.io.*;
class FileReaderTest
{
public static void main(String[] args) throwsIOException
{
FileReader fr = new FileReader("FileReaderDemo2.java");
//定义一个字符数组,用于存储读到的字符。
//该read(char[])返回的是读到字符个数
char[] buf = new char[1024];
int num = 0;
while ((num=fr.read(buf))!=-1)
{
System.out.print(new String(buf,0,num));
}
fr.close();
}
}
演示6:
importjava.io.*;
class CopyTest
{
public static void main(String[] args) throwsIOException
{
copy_2();
}
//从c盘读一个字符,就往d盘写一个字符。
public static void copy_2()
{
FileWriter fw = null;
FileReader fr = null;
try
{
fw = newFileWriter("D:\\test\\FileReaderDemo2_copy.java");
fr = new FileReader("FileReaderDemo2.java");
char[] buf = new char[1024];
int len = 0;
while ((len=fr.read(buf))!=-1)
{
fw.write(buf,0,len);
}
}
catch (IOException e)
{
throw new RuntimeException("读写失败");
}
finally
{
if(fr!=null)
try
{
fr.close();
}
catch (IOException e)
{
}
if(fw!=null)
try
{
fw.close();
}
catch (IOException e)
{
}
}
}
public static void copy_1() throws IOException
{
//创建目的地
FileWriter fw = newFileWriter("D:\\test\\FileReaderDemo2_copy.java");
FileReader fr = new FileReader("FileReaderDemo2.java");
int ch = 0;
while ((ch=fr.read())!=-1)
{
fw.write(ch);
}
fw.close();
fr.close();
}
}
字符流的缓冲区
缓冲区的出现提高了对数据的读写效率
对应类:BufferedWriter BufferedReader
缓冲区要结合流才可以使用
在流的基础上对流的功能进行了增强。
演示1:
importjava.io.*;
class BufferedWriterDemo
{
public static void main(String[] args) throwsIOException
{
//创建一个字符写入流对象
FileWriter fw = new FileWriter("buf.txt");
//为了提高字符写入流效率,加入了缓冲技术
//只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可。
BufferedWriter bufw = new BufferedWriter(fw);
for (int x=1;x<5 ;x++ )
{
bufw.write("abcd"+x);
bufw.newLine();
bufw.flush();
}
//记住,只要用到缓冲区,就要记得刷新
//bufw.flush();
//其实关闭缓冲区,就是关闭缓冲区中的流对象
bufw.close();
}
}
示例2:
importjava.io.*;
class BufferedReaderDemo
{
public static void main(String[] args) throwsIOException
{
//创建一个读取流对象的文件相关联
FileReader fr = new FileReader("buf.txt");
//为了提供效率,加入缓冲技术。将字符读取流对象作为参数传递给缓冲对象的构造函数。
BufferedReader bufr = new BufferedReader(fr);
String line = null;
while ((line=bufr.readLine())!=null)
{
System.out.println(line);
}
bufr.close();
}
}
示例3:
importjava.io.*;
class CopyTextByBuf
{
public static void main(String[] args)
{
BufferedReader bufr = null;
BufferedWriter bufw = null;
try
{
bufr = new BufferedReader(newFileReader("BufferedWriterDemo.java"));
bufw = new BufferedWriter(newFileWriter("bufferWriter_copy.txt"));
String line = null;
while ((line=bufr.readLine())!=null)
{
bufw.write(line);
bufw.newLine();
bufw.flush();
}
}
catch (IOException e)
{
throw new RuntimeException("读写失败");
}
finally
{
try
{
if(bufr!=null)
bufr.close();
}
catch (IOException e)
{
throw new RuntimeException("读写失败");
}
}
}
}
示例4:
importjava.io.*;
class MyBufferedReader
{
private FileReader r;
MyBufferedReader(FileReader r)
{
this.r = r;
}
//可以一次读一行数据的方法
public String myReadLine() throws IOException
{
//定义一个临时容器。原BufferReader封装的是字符数组。
//为了演示方便。定义一个StingBuilder容器。因为最终还是要将数据变成字符串。
StringBuilder sb = new StringBuilder();
int ch = 0;
while ((ch=r.read())!=-1)
{
if(ch=='\r')
continue;
if(ch=='\n')
return sb.toString();
else
sb.append((char)ch);
}
if(sb.length()!=0)
return sb.toString();
return null;
}
public void myClose()throws IOException
{
r.close();
}
}
classMyBufferedReaderDemo
{
public static void main(String[] args) throwsIOException
{
FileReader fr = new FileReader("buf.txt");
MyBufferedReader myBuf = new MyBufferedReader(fr);
String line = null;
while ((line=myBuf.myReadLine())!=null)
{
System.out.println(line);
}
myBuf.myClose();
}
}
装饰设计模式:
当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供加强功能,那么自定义的该类称为装饰类。
装饰类通常会通过构造函数方法接收被装饰的对象,并基于被装饰的对象的功能,提供更强的功能。
装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强的功能。
所以装饰类和被装饰类通常是都属于一个体系中的。
装饰模式比继承更灵活,避免了继承体系臃肿
而且降低了类与类之间的关系。
读取转换流
示例:
importjava.io.*;
class TransStreamDemo
{
public static void main(String[] args) throwsIOException
{
//获取键盘录入对象
InputStream in = System.in;
//将字节流对象转成字符流对象,使用转换流InputStreamReader
InputStreamReader isr = new InputStreamReader(in);
//为了提高效率,将字符串进行缓冲区技术高效操作,使用BufferedReader
BufferedReader bufr = new BufferedReader(isr);
String line = null;
while ((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
System.out.println(line.toUpperCase());
}
bufr.close();
}
}
写入流转换:
示例
importjava.io.*;
class TransStreamDemo
{
public static void main(String[] args) throwsIOException
{
//获取键盘录入对象
//InputStream in = System.in;
//将字节流对象转成字符流对象,使用转换流InputStreamReader
//InputStreamReader isr = new InputStreamReader(in);
//为了提高效率,将字符串进行缓冲区技术高效操作,使用BufferedReader
//BufferedReader bufr = new BufferedReader(isr);
//以上三句话下面一句话。键盘的最常见写法。
BufferedReader bufr
= newBufferedReader(new InputStreamReader(System.in));
//OutputStream out = System.out;
//OutputStreamWriter osw = new OutputStreamWriter(out);
//BufferedWriter bufw = new BufferedWriter(osw);
//以上三句话合并一句话。
BufferedWriterbufw
= newBufferedWriter(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();
}
bufr.close();
}
}
演示结果:
jklkjlk
JKLKJLK
kljklhh
KLJKLHH
Over
流操作的基本规律:
通过两个明确来完成:
1、 明确源和目的
源:输入流 InputStream Reader
目的:输出流 OutputStream Writer
2、 操作的数据是否是纯文本。
是:字符流
否:字节流
3、 当体系明确后,再明确要使用哪个具体的对象
通过设备来进行区分
源设备:内存、硬盘、键盘
目的设备:内存、硬盘、控制台
1、 将一个文本文件中数据存储到另外一个文件中。复制文件
源:因为是源,所以使用读取流 InputStream Reader
是不是操作文本文件
是 选择Reader
这样体系就明确了
接下来明确要使用该体系中的哪个对象
明确设备:硬盘上一个文件
Reader体系中可以操作文件的对象是FileReader
是否要提供效率:
FileReader fr =new FileReader(“a.txt”);
BufferedReaderbufr = new BufferedReader(fr);
目的:OutputStream Writer
是否是纯文本
是 Writer
设备:硬盘的一个文件
Writer体系中可以操作文件的对象FileWriter
是否需要提供效率
是 加入writer体系中缓冲区BufferedWriter
FileWriter fw =new FileWriter();
BufferedWriterbufw = new BufferedWriter(fw);
2、 需求:将键盘录入的数据保存到一个文件中
源:InputStream Reader
是不是文本? 是 Reader
设备:键盘 对应的对象是System.in
不是选择Reader吗?System.in对应的不是字节流吗?
为了操作键盘的文件数据方便,转成字符流按照字符串操作是最方便的。
所以既然明确了Reader,那么就将System.in转换成Reader。
用了Reader体系中的转换流,InputStreamReader
InputStreamReader isr = newInputStreamReader(System.in);
需要提高效率吗?
需要!BufferedReader
BufferedReaderbufr = new BufferedReader(isr);
目的:OutputStream Writer
是否是纯文本?
是!Writer
设备:硬盘 一个文件 使用FileWriter
FileWriter fw =new FileWriter(“x.txt”);
需要提高效率吗?
需要!
BufferedWriterbufw = new BufferedWriter(fw);
扩展一下,想要把录入的数据按照指定的编码表(utf-8),将数据存到文件中。
目的:OutputStream Writer
是否是纯文本?是 Writer
设备:硬盘 一个文件 使用FileWriter
但是FileWriter是使用的默认编码表GBK
但是存储时,需要加入指定编码表utf-8.而指定的编码表只有流转换可以指定。
所以要使用的对象是OutputStreamWriter
而该转换流对象要接收一个字节输出流。而且还可以操作的文件的字节输出流。FileOutputStream
OutputStreamWriterosw = new OutputStreamWriter(newFileOutputStream(“d.txt”),“UTF-8”);
需要高效吗?
需要
BufferedWriter bufw =new BufferedWriter(osw);
所以记住。转换流什么时候使用?字符和字节之间的桥梁,通常涉及到字符编码转换时需要用到转换流。
改变标准输入输出设备
示例1:
importjava.io.*;
class SystemInDemo
{
public static void main(String[] args) throwsIOException
{
System.setIn(newFileInputStream("CopyTest.java"));
System.setOut(new PrintStream("zzz.txt"));
//实现了复制的功能
BufferedReader bufr = new BufferedReader(newInputStreamReader(System.in));
BufferedWriter bufw
= new BufferedWriter(newOutputStreamWriter(System.out));
String line = null;
while ((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();//回车换行,通用
bufw.flush();
}
bufr.close();
}
系统信息
importjava.util.*;
importjava.io.*;
class SystemInfo
{
public static void main(String[] args) throwsIOException
{
Properties prop = System.getProperties();
//System.out.println(prop);
prop.list(new PrintStream("sysinfo.txt"));
}
}