读取键盘录入:
System.out:对应的是标准输出设备,控制台
System.in:对应的是标准输入设备,键盘
通过键盘输入显示在dos窗口中
import java.io.*;
class SystemTest1
{
public static void main(String[] args) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));//创建一个读入缓冲区
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));//创建一个写入缓冲区
String s=br.readLine();//将写入的字符串复制给s
s=s.toUpperCase();//将字符串变大写
bw.write(s);//输出
br.close();
bw.close();
}
}
通过上面的程序可以看出只要更改InputStreamReader和OUtputStreamWriter中传递的参数就可以从指定地方读,写到指定地方
改变标准输入输出设备可以用System.setIn和System.setOut改变:
例如System.setIn(new FileInputStream("per.java"));
System.setOut(new PrintStream("sd.log"));//这个好想只能new printStream,其他的编译失败
当录入的数据按照指定的编码表(UTF-8)将数据存入到文件中时
在存储时,需要加入指定的编码表,而指定编码表只能只有转换流可以指定,所以要使用的对象是OutputStreamWriter()而该转化流对象要接收一个字节输出流,而且还可以操作文件的字节输出流。
转换使用条件:
字符和字节之间桥梁,通常涉及到字符编码转换时需要用到转换流
例如下面程序:
import java.io.*;
class CharsetText
{
public static void main(String[] args) throws IOException
{
FileReader fr=new FileReader("1.txt");//打开一个字符文件
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("2.txt"),"iso-8859-2");//字节的形式写入到文件中
int num=0;
while((num=fr.read())!=-1)
{
osw.write(num);
}
fr.close();
osw.close();
}
}
让面的的编码参数如果和源文件一致不会出现乱码,当不一致时会出现乱码;
异常的日记信息:
有一款软件log4j是专门处理异常日记的软件,很好用
File类:
用来将文件或者文件夹封装成对象,方便对文件和文件夹的属性进行操作
File对象可以作为参数传递给流的构造函数
在此对象上有个跨平台的分隔符File.separator(\);
File类常见方法:
1、创建
createNewFile()
createNewFile在创建对象时不过文件是什么类型只要名字一致他就不会创建文件,如果相同目录下有t.txt文件将不能被创建
mkdir()只能创建一级目录
mkdirs()可以创建多级目录
2、删除
delete()//删除文件和目录,如果目录不为空则无法实现删除
deleteOnExit()退出时删除
3、判断
canExecute()测试应用程序是否可以执行此抽象路径名表示的文件。
exists()指定目录下是否存在指定文件
isHidden()指定文件是否隐藏
isDirectory()测试此抽象路径名表示的文件是否是一个目录
isAbsolute()判断文件是否是绝对路径(文件不存在也可以判断)
isFile()测试此抽象路径名表示的文件是否是一个标准文件
4、获取
getName()获取文件或目录名
getPath()获取传入的路径
getParent()获取绝对路径下的根目录
getAbsolute() 获取绝对路径
5、其他的方法
renameTo重命名
listRoot()列出可用文件根目录
list()打印指定目录下所有文件(包括隐藏文件)调用list方法的file对象必须是封装了一个目录,该目录还必须存在
练习将一个目录下的所有java文件名的绝对路径打印到一个文件中:
import java.io.*;
import java.util.*;
class FileTest
{
public static void main(String[] args)
{
File file=new File("F:\\java");
List<File> list=new ArrayList<File>();
String fileList="fileList.txt";
getFileList(file,list);
print(list,fileList);
}
public static void getFileList(File dir,List<File> list)
{
File[] files=dir.listFiles();
for(File file:files)//增强型for可以直接遍历Collection集合和数组
{
if(file.isDirectory())//判断是否为目录
getFileList(file,list);
else
if(file.getName().endsWith(".java"))//判断是否为java文件并将java文件增加到List上
list.add(file);
}
}
public static void print(List<File> list,String fileList)
{
BufferedWriter bw=null;
try{
bw=new BufferedWriter(new FileWriter(fileList));
for(File file:list)
{
String dir=file.getAbsolutePath();//得到文件的绝对路径
bw.write(dir);
bw.newLine();
bw.flush();
}
}
catch(IOException e)
{
System.out.println("写入异常");
}
finally
{
try{
bw.close();
}
catch(IOException e1)
{
}
}
}
}
本程序通过递归来实现的
删除一个带内容的目录:
import java.io.*;
class FileTest1
{
public static void main(String[] args)
{
File file=new File("aaaa");
getFileList(file);
}
public static void getFileList(File dir)
{
if(!dir.delete())//判断当没有删除时遍历目录
{
File[] files=dir.listFiles();
for(File file:files)//遍历当前文件下的文件
getFileList(file);
dir.delete();//将当前文件内的文件都删完后删掉自己
}
}
}
Properites对象
Properties是HashTable的子类,也就是说它具有map集合的特点,是集合中IO技术相结合的集合容器,该对象的特点可以用于键值对的形式的配置文件
load(InputStream inStream)
从输入流中读取属性列表(键和元素对)。
list(PrintStream out) 将属性列表输出到指定的输出流。
list(PrintWriter out) 将属性列表输出到指定的输出流。
Propertoes加载的数据必须是键值对,需要数据有固定格式
打印流
PrintWriter和PrintStream
该流提供了打印方法,可以将各种数据类型的数据到原样打印
字节打印流
PrintStream
构造函数:
1、File对象
2、字符串路径String
3、字节输出流:OutputStream
字符打印流:
PrintWriter
构造函数可以接收参数类型:
1、File对象
2、字符串路径
3、字节输出流
4、字符输出流
打印流就是将获得的数据打印到指定的位置上例如:
import java.io.*;
class PrintStreamTest
{
public static void main(String[] args) throws IOException
{
BufferedReader bw=new BufferedReader(new InputStreamReader(System.in));
String str=bw.readLine();
//PrintWriter pw=new PrintWriter(new OutputStreamWriter(System.out));//打印到控制台上
PrintWriter pw=new PrintWriter(new FileWriter("11.txt"));//打印到当前目录下的11.txt目录下
str=str.toUpperCase();
pw.println(str);
bw.close();
pw.close();
}
}
切割文件:
序列流:
SequenceInputStream(合并切割的文件) 没有对应的Output
下面是对文件进行分割后在合并起来的程序
import java.io.*;
import java.util.*;
class SplitFileTest
{
public static void main(String[] args) throws IOException
{
String filePath="1.wmv";
ArrayList<File> al=new ArrayList<File>();//这个地方设成File是为了在切割和合并中都可以用
split(al,filePath);
String fileDecoPath="zuhe.wmv";
sequenceFile(al,fileDecoPath);
}
public static void split(ArrayList<File> al,String filePath)throws IOException//切割文件
{
BufferedInputStream bis=new BufferedInputStream(new FileInputStream(filePath));
byte[] buf=new byte[1024*1024];//规定每个碎片的的大小
int len=0;
int count=0;
while((len=bis.read(buf))!=-1)
{
File file=new File("splits"+(count++)+".part");
FileOutputStream fos=new FileOutputStream(file);
al.add(file);
fos.write(buf,0,len);
fos.close();//每生成一个就要关闭它
}
bis.close();
}
public static void sequenceFile(ArrayList<File> al,String fileDecoPath)throws IOException//合并碎片文件
{
final Iterator<File> it=al.iterator();//因为内部类只能访问被final修饰的局部变量
Enumeration<FileInputStream> en=new Enumeration<FileInputStream>()//将迭代器中的数据转化为枚举类型
{
public boolean hasMoreElements()
{
return it.hasNext();
}
public FileInputStream nextElement()//将File文件转换成FileInputStream
{
FileInputStream fis=null;
try{
fis=new FileInputStream(it.next());//因为父类没有抛异常,所以这个地方只能try
}
catch(IOException e)
{
System.out.println("碎片文件没有正确打开");
}
return fis;
}
};
SequenceInputStream sis=new SequenceInputStream(en);//碎片合成一个流对象
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(fileDecoPath));
int len=0;
byte[] buf=new byte[1024*5];
while((len=sis.read(buf))!=-1)
{
bos.write(buf,0,len);
bos.flush();//对于多字节的最好设定刷新,避免一些特殊情况发生比如断电
}
bos.close();
sis.close();
}
}
IO中的其他类:
ObjectInputStream和ObjectOutputStream
被操作的对象应该实现Serializable接口例如:
import java.io.*;
class ObjectStreamTest
{
public static void main(String[] args) throws Exception
{
objectOutput();
objectInput();
}
public static void objectInput()throws Exception
{
ObjectInputStream ois =new ObjectInputStream(new FileInputStream("a.txt"));
Object obj=null;
while(true)
{
try{
obj=ois.readObject();//为了让其读完后停止,用抛异常的方法将其暂停
}catch(Exception e)
{
break;
}
if(obj instanceof Person)//判断输入的对象时Person类
{
Person p=(Person)obj;
System.out.println(p.name+":"+p.age+":"+p.country);
}
}
}
public static void objectOutput()throws IOException
{
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("a.txt"));
oos.writeObject(new Person("zjd1",23,"uk"));
oos.writeObject(new Person("zjd2",23,"uk"));
oos.writeObject(new Person("zjd3",23,"uk"));
oos.close();
}
}
被操作的对象:
import java.io.*;
class Person implements Serializable//必须实现Seralizable接口
{
public static final long serialVersionUID = 42L;//指定类的标志符
public String name;
transient int age;//如果成员变量不是静态的又不想将其序列化,那么可以在前加上transient
static String country="cn";//静态变量不能被序列化
Person(String name,int age,String country)
{
this.name=name;
this.age=age;
this.country=country;
}
}
RandomAccessFile类:随机访问文件,自身具备读写的方法
通过skipBytes(int x)(只能上前奏)和seek(int x)(可以将指针变化到任意地方)来达到随机访问:
此类主要用于多线程下载
他在操作文件的时候有r、rw等模式
当为读模式时不会创建文件,会读取一个已存在的文件,如果不存在则抛出异常,当为读写模式时,如果文件不存在则创建新文件,如果存在则不会覆盖。
操作基本数据类型
DataInputStream和DataOutputStream:只要操作基本数据类型就用到它,并且他们要成对出现
操作字符数组:
ByteArrayInputStream和ByteArrayOutputStream:他没有调用任何底层资源所以不需要关流,即使关掉也不会其任何作用,还可以和继续读写,ByteArrayInputStream在构造时需要传入数据源,而数据源是个字符数组,第二个不需要传入任何参数,他们的字节长度是可变的,对于他不传入参数,是因为该对象已将内部封装了可变长度的字节数组,这就是数据目的地
因为这两个流对象都操作的是数组,并没有使用系统资源,所以不需要进行关闭
操作字符数组:
CharArrayReader和CharArrayWrite
操作字符串数组:
StringReader和StringWriter
字符编码:
1、字符流的出现是为了方便操作字符
2、更重要的是加入了编码转换
3、通过子类转化流来完成
InputStreamReader和OutputStreamWriter
编码:字符串转化为字节
解码:字节转化为字符串