File类
用来将文件或者文件夹封装成对象。方便对文件与文件夹进行操作。File对象可以作为参数传递给流的构造函数。
importjava.io.*;
classFileDemo
{
public static void main(String[] args)
{
consMethod();
}
//创建File对象
public static void consMethod()
{
//将a.txt封装成file对象,可以将已有的和未出现的文件或者文件夹封装成对象
File f1=newFile("c:\\abc\\a.txt");
File f2=newFile("c:\\abc","b.txt");
File d=newFile("c:\\abc");
File f3=newFile(d,"c.txt");
sop("f1:"+f1);
sop("f2:"+f2);
sop("f3:"+f3);
//目录分隔符separator
File f4=newFile("c:"+File.separator+"abc\\zz"+File.separator+"d.txt");
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
File类常见方法:
1、创建
boolean createNewFile();在指定位置创建文件,如果该文件已经存在,则不创建,返回false。
和输出流不一样,输出流对象一建立就创建文件,而且文件已经存在,会覆盖。
boolean mkdir():创建文件夹
boolean mkdirs():创建多级目录
2、删除
boolean delete();删除失败返回false。
void deleteOnExit();在程序退出时删除指定文件。
3、判断
canExecute();是否能执行
boolean exists():文件是否存在
isDirctory():是否是一个目录
isFile():是否是一个文件
isHidden():是否是隐藏
isAbsolute():是否是绝对路径
4、获取信息
getName();
getPath();路径
getParent();
getAbsoutePath();绝对路径
lastModidied();最后一次修改时间
length();
importjava.io.*;
classFileDemo1
{
public static void main(String[] args)
{
method_5();
}
public static void method_5()
{
File f1=newFile("c:\\T.java");
File f2=newFile("c:\\H.java");
sop("rename:"+f1.renameTo(f2));
}
public static void method_4()
{
File f=newFile("abc\\a.txt");
sop("path:"+f.getPath());
sop("abspath:"+f.getAbsolutePath());
sop("parent:"+f.getParent());//该方法返回的是绝对路径中的父目录,如果获取的是相对路径,返回null
//如果相对路径中有上一层目录,则该目录就是返回结果。
}
public static void method_3()throwsIOException
{
File f=newFile("file.txt");
f.createNewFile();
f.mkdir();
//记住在判断文件对象是否是文件或者目录时,必须先判断该文件对象封装的内容是否存在
//通过exists判断
sop("dir:"+f.isDirectory());
sop("file:"+f.isFile());
}
public static void method_2()throwsIOException
{
File f=new File("file.txt");
//sop("exists:"+f.exists());
//sop("execute:"+f.canExecute());
//创建文件夹
File dir=new File("abc\\aa");
sop("dir:"+dir.mkdir());//只能创建两级
}
public static void method_1()throwsIOException
{
File f=newFile("file.txt");
sop("create="+f.createNewFile());
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
调用list方法的File对象必须是封装了一个目录,该目录还必须存在
importjava.io.*;
classFileDemo2
{
public static void main(String[] args)
{
//listDemo();
File dir=newFile("c:\\");
File[] files=dir.listFiles();
for(File f:files)
{
System.out.println(f.getName()+"::"+f.length());
}
}
public static void listDemo()
{
File dir=newFile("c:\\");
String[] arr=dir.list(newFilenameFilter()
{
public boolean accept(File dir,Stringname)
{
returnname.endsWith(".zip");
}
});
for(String name:arr)
{
System.out.println(name);
}
}
}
列出指定目录下文件或文件夹,包括子目录中的内容。
也就是列出指定目录下所有内容。
因为目录中还有目录,只要使用同一个列出目录功能的函数完成即可。
在列出过程中出现的还是目录的话,还可以再次调用本功能。
也就是函数自身调用自身。
这种表现形式,或者编程手法,称为递归。
递归注意:
1、限定条件
2、要注意递归的次数,尽量避免内存溢出。
importjava.io.*;
classFileDemo3
{
public static void main(String[] args)
{
File dir=newFile("d:\\java");
showDir(dir);
}
public static void showDir(File dir)
{
File[] files=dir.listFiles();
for(int x=0;x<files.length;x++)
{
if(files[x].isDirectory())
showDir(files[x]);
else
System.out.println(files[x]);
}
}
}
带层次列出:
列出指定目录下文件或文件夹,包括子目录中的内容。
也就是列出指定目录下所有内容。
因为目录中还有目录,只要使用同一个列出目录功能的函数完成即可。
在列出过程中出现的还是目录的话,还可以再次调用本功能。
也就是函数自身调用自身。
这种表现形式,或者编程手法,称为递归。
递归注意:
1、限定条件
2、要注意递归的次数,尽量避免内存溢出。
importjava.io.*;
classFileDemo3
{
public static void main(String[] args)
{
File dir=newFile("d:\\java");
showDir(dir,0);
}
public static String getLevel(intlevel)
{
StringBuilder sb=newStringBuilder();
sb.append("|--");
for(int x=0;x<level;x++)
{
sb.insert(0," ");
}
return sb.toString();
}
public static void showDir(File dir,intlevel)
{
//System.out.println(getLevel(level)+dir.getName());
level++;
File[] files=dir.listFiles();
for(int x=0;x<files.length;x++)
{
if(files[x].isDirectory())
showDir(files[x],level);
else
System.out.println(getLevel(level)+files[x]);
}
}
}
练习:
将一个指定目录下的java文件的绝对路径,存储到一个文本文件中。
建立一个java文件列表文件。
思路:
1、对指定的目录进行递归。
2、获取递归过程中所有的java文件的路径
3、将这些路径存储到集合中。
4、将集合中的数据写入到一个文件中。
importjava.io.*;
importjava.util.*;
class JavaFileList
{
public static void main(String[] args)throws IOException
{
File dir=newFile("d:\\java");
List<File> list=newArrayList<File>();
fileToList(dir,list);
//System.out.println(list.size());
File file=newFile(dir,"javalist.txt");
writeToFile(list,file.toString());
}
public static void fileToList(Filedir,List<File> list)
{
File[] files=dir.listFiles();
for(File file:files)
{
if(file.isDirectory())
fileToList(file,list);
else
{
if(file.getName().endsWith(".java"))
list.add(file);
}
}
}
public static voidwriteToFile(List<File> list,String javaListFile)throws IOException
{
BufferedWriter bufw=null;
try
{
bufw=newBufferedWriter(new FileWriter(javaListFile));
for(File f:list)
{
Stringpath=f.getAbsolutePath();
bufw.write(path);
bufw.newLine();
bufw.flush();
}
}
catch (IOException e)
{
throw e;
}
finally
{
try
{
if(bufw!=null)
bufw.close();
}
catch (IOExceptione)
{
throw e;
}
}
}
}
Propertiers是hashtable的子类
也就是说它具备map集合的特点,而且它里面存储的键值对都是字符串。
是集合中和IO技术相结合的集合容器。
该对象的特点:可以用于键值对形式的配置文件.
那么在加载数据时,需要数据有固定格式:键=值。
importjava.io.*;
importjava.util.*;
class PropertiesDemo
{
public static void main(String[] args)throws IOException
{
loadDemo();
}
public static void loadDemo()throwsIOException
{
Properties prop=new Properties();
FileInputStream fis=newFileInputStream("info.txt");
//将流中的数据加载进集合。
prop.load(fis);
prop.setProperty("wangwu","99");
FileOutputStream fos=newFileOutputStream("info.txt");
prop.store(fos,"haha");
//System.out.println(prop);
prop.list(System.out);
fos.close();
fis.close();
}
演示,如何将流中的数据存储到集合中。
想要将info.txt中键值数据存到集合中进行操作。
1、用一个流和info.txt文件关联。
2、读取一行数据,将该行数据用“=”进行分割。
3、等号左边作为键,邮编作为值,存入到Properties集合中即可。
public static void method_1()throwsIOException
{
BufferedReader bufr=newBufferedReader(new FileReader("info.txt"));
String line=null;
Properties prop=newProperties();
while((line=bufr.readLine())!=null)
{
String[]arr=line.split("=");
//System.out.println(arr[0]+"....."+arr[1]);
prop.setProperty(arr[0],arr[1]);
}
bufr.close();
}
//设置和获取元素。
public static void setAndGet()
{
Properties prop=newProperties();
prop.setProperty("zhangsan","30");
prop.setProperty("lisi","39");
Stringvalue=prop.getProperty("lisi");
System.out.println(value);
Set<String>names=prop.stringPropertyNames();
for(String s:names)
{
System.out.println(s+":"+prop.getProperty(s));
}
}
}
打印流:
该流提供了打印方法,可以将各种数据类型的数据都原样打印。
字节打印流:
PrintStream
构造函数可以接收的参数类型:
1、file对象。File
2、字符串路径。String
3、字节输出流。OutputStream
字符打印流:
PrintWriter
构造函数可以接收的参数类型:
1、file对象。File
2、字符串路径。String
3、字节输出流。OutputStream
4、字符输出流。Writer
importjava.io.*;
class PrintStreamDemo
{
public static void main(String[] args)throws IOException
{
BufferedReader bufr=newBufferedReader(new InputStreamReader(System.in));
//PrintWriter out=newPrintWriter(System.out,true);
PrintWriter out=newPrintWriter(new FileWriter("a.txt"),true);
String line=null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
out.println(line.toUpperCase());
}
out.close();
bufr.close();
}
}
合并流:
importjava.io.*;
importjava.util.*;
class SequenceDemo
{
public static void main(String[]args)throws IOException
{
Vector<FileInputStream>v=new Vector<FileInputStream>();
v.add(newFileInputStream("d:\\1.txt"));
v.add(newFileInputStream("d:\\2.txt"));
v.add(newFileInputStream("d:\\3.txt"));
Enumeration<FileInputStream>en=v.elements();
SequenceInputStream sis=newSequenceInputStream(en);
FileOutputStream fos=newFileOutputStream("d:\\4.txt");
byte[] buf=new byte[1024];
int len=0;
while((len=sis.read(buf))!=-1)
{
fos.write(buf,0,len);
}
fos.close();
sis.close();
}
}
切割流然后合并:
importjava.io.*;
importjava.util.*;
classSplitFile
{
public static void main(String[] args)throws IOException
{
merge();
}
public static void merge()throwsIOException
{
ArrayList<FileInputStream>al=new ArrayList<FileInputStream>();
for(int x=1;x<3;x++)
{
al.add(newFileInputStream("d:\\java\\SplitFile\\"+x+".part"));
}
finalIterator<FileInputStream> it=al.iterator();
Enumeration<FileInputStream>en=new Enumeration<FileInputStream>()
{
public booleanhasMoreElements()
{
returnit.hasNext();
}
publicFileInputStream nextElement()
{
returnit.next();
}
};
SequenceInputStream sis=newSequenceInputStream(en);
FileOutputStream fos=newFileOutputStream("d:\\java\\SplitFile\\0.jpg");
byte[] buf=new byte[1024];
int len=0;
while((len=sis.read(buf))!=-1)
{
fos.write(buf,0,len);
}
fos.close();
sis.close();
}
public static void splitFile()throwsIOException
{
FileInputStream fis=newFileInputStream("d:\\1.jpg");
FileOutputStream fos=null;
byte[] buf=newbyte[1024*1024];
int len=0;
int count=1;
while((len=fis.read(buf))!=-1)
{
fos=newFileOutputStream("d:\\java\\SplitFile\\"+(count++)+".part");
fos.write(buf,0,len);
fos.close();
}
fis.close();
}
}
管道流
importjava.io.*;
classPipedStream
{
public static void main(String[] args)throws IOException
{
PipedInputStream in=newPipedInputStream();
PipedOutputStream out=newPipedOutputStream();
in.connect(out);
Read r=new Read(in);
Write w=new Write(out);
new Thread(r).start();
new Thread(w).start();
}
}
class Readimplements Runnable
{
private PipedInputStream in;
Read(PipedInputStream in)
{
this.in=in;
}
public void run()
{
try
{
byte[] buf=newbyte[1024];
System.out.println("读取前。。没有数据,阻塞。。");
intlen=in.read(buf);
System.out.println("读到数据。。阻塞结束");
String s=newString(buf,0,len);
System.out.println(s);
in.close();
}
catch (IOException e)
{
throw newRuntimeException("管道读取流失败");
}
}
}
class Writeimplements Runnable
{
private PipedOutputStream out;
Write(PipedOutputStream out)
{
this.out=out;
}
public void run()
{
try
{
System.out.println("开始写入数据,等待6秒后。。。");
Thread.sleep(6000);
out.write("nimei de keng die".getBytes());
out.close();
}
catch (Exception e)
{
throw newRuntimeException("管道输出流失败");
}
}
}
RandomAccessFile
该类不算是IO体系中子类。
而是直接继承自Object。
但是它是IO包中的成员,因为它具备读和写功能。
内部封装了一个数组,而且通过指针对数组的元素进行操作。
可以通过getFilePointer获取指针位置,
同时可以通过seek改变指针的位置。
其实完成读写的原理就是内部封装了字节输入流和输出流。
通过构造函数可以看出,该类只能操作文件。
而且操作文件还有模式:只读r,读写rw等。
如果模式为只读r,则不会创建文件,会去读取一个已存在的文件,如果该文件不存在,则会出现异常。
如果模式是读写rw,操作的文件不存在,会自动创建,如果存在则不会覆盖。
importjava.io.*;
class RandomAccessFileDemo
{
public static void main(String[] args)throws IOException
{
//writeFile();
readFile();
}
public static void readFile()throws IOException
{
RandomAccessFile raf=newRandomAccessFile("ran.txt","r");
//调整对象中指针。
//raf.seek(8);
//raf.skipBytes(8);//不能往回走
byte[] buf=new byte[4];
raf.read(buf);
String name=new String(buf);
int age=raf.readInt();
System.out.println("name="+name);
System.out.println("age="+age);
raf.close();
}
public static void writeFile2()throwsIOException
{
RandomAccessFile raf=newRandomAccessFile("ran.txt","rw");
raf.seek(8*3);//设置位置
raf.write("周七".getBytes());
raf.writeInt(103);
raf.close();
}
public static void writeFile()throwsIOException
{
RandomAccessFile raf=newRandomAccessFile("ran.txt","rw");
raf.write("李四".getBytes());
raf.writeInt(97);
raf.write("王五".getBytes());
raf.writeInt(99);
raf.close();
}
}
打印流:PrintWriter与PrintStream可以直接操作输入流和文件
序列流:SequenceInputStream对多个流进行合并
操作对象:ObjectInputStream与ObjectOutputStream被操作的对象需要实现Serializable
序列化接口:Serializable
管道流:PipedInputStream和PipedOutputStream,输入输出可以直接进行连接,通过结合线程使用。
RandomAccessFile
随机访问文件,自身具备读写的方法。
通过skipBytes(intx),seek(int x)来达到随机访问。
IO包中的其他流:
操作基本数据类型:DataInputStream和DataOutputStream
DataInputStream与DataOutputStream
可以用于操作基本数据类型的数据流对象
importjava.io.*;
class DataStreamDemo
{
public static void main(String[] args)throws IOException
{
//writeData();
//readData();
//writeUTFDemo();
//OutputStreamWriter osw=newOutputStreamWriter(newFileOutputStream("utf.txt","utf-8"));
//dos.write("你好");//此文件6个字节
//dos.close();
readUTFDemo();
}
public static void readUTFDemo()throwsIOException
{
DataInputStream dis=newDataInputStream(new FileInputStream("utfdata.txt"));
String s=dis.readUTF();
System.out.println(s);
dis.close();
}
public static void writeUTFDemo()throwsIOException
{
DataOutputStream dos=new DataOutputStream(newFileOutputStream("utfdata.txt"));
dos.writeUTF("你好");//此文件8个字节,只能用DataInputStream读
dos.close();
}
public static void readData()throwsIOException
{
DataInputStream dis=newDataInputStream(new FileInputStream("data.txt"));
int num=dis.readInt();
boolean b=dis.readBoolean();
double d=dis.readDouble();
System.out.println("num="+num);
System.out.println("b="+b);
System.out.println("d="+d);
}
public static void writeData()throwsIOException
{
DataOutputStream dos=newDataOutputStream(new FileOutputStream("data.txt"));
dos.writeInt(234);
dos.writeBoolean(true);
dos.writeDouble(9887.543);
dos.close();
}
}
编码表:
计算机只能识别二进制数据,早期由来是电信号。为了方便应用计算机,让它可以识别各个国家的文字。就将各个国家的文字用数字表示,并一一对应,形成一张表,这就是编码表。
ASCII:美国标准信息交换码。用一个字节的7位可以表示。
ISO8859-1:拉丁码表,欧洲码表。用一个字节的8位表示。
GB2312:中国的中文编码表。
GBK:中国的中文编码表升级,融合了更多的中文文字符号。
Unicode:国际标准码,融合了多种文字,所有文字都用两个字节来表示。java语言使用的就是unicode。
UTF-8:最多用三个字节来表示一个字符。
importjava.io.*;
classEncodeStream
{
public static void main(String[] args)throws IOException
{
//writeText();
readText();
}
public static void readText()throwsIOException
{
//InputStreamReader isr=newInputStreamReader(new FileInputStream("utf.txt"),"GBK");
InputStreamReader isr=newInputStreamReader(new FileInputStream("gbk.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()throwsIOException
{
OutputStreamWriter osw =newOutputStreamWriter(newFileOutputStream("utf.txt"),"UTF-8");
//OutputStreamWriter osw =newOutputStreamWriter(new FileOutputStream("gbk.txt"),"GBK");
osw.write("你好");
osw.close();
}
}
编码:字符串变成字节数组
解码:字节数组变成字符串
String-->byte[];str.getBytes(charsetName);
byte[]-->String:newString(byte[],charsetName);
class EncodeDemo
{
public static void main(String[] args)throws Exception
{
String s="你好";
byte[]b1=s.getBytes("GBK");
String s1=newString(b1,"ISO8859-1");
//对s1进行ISO8859-8编码
byte[]b2=s1.getBytes("ISO8859-1");
String s2=newString(b2,"GBK");
System.out.println("s1="+s2);
//System.out.println(Array.toString(b1));
}
}
有五个学生,每个学生有3门课的成绩。
从键盘输入以上数据(包括姓名,三门课成绩),
输入格式:如:zhangsan,30,40,60计算出总成绩,
并把学生的信息和计算出的总分数高低顺序存放在磁盘文件"stud.txt"中。
1、描述学生对象。
2、定义一个可操作学生对象的工具类。
思想:
1、通过获取键盘录入一行数据,并将该行中的信息取出封装成学生对象。
2、因为学生有很多,那么就需要存储,使用到集合,因为要对学生的总分排序,
所以可以使用TreeSet。
3、将集合的信息写入到一个文件中。
importjava.io.*;
importjava.util.*;
class StudentInfoTest
{
public static void main(String[] args)throws IOException
{
Comparator<Student>cmp=Collections.reverseOrder();
Set<Student>stus=StudentInfoTool.getStudents(cmp);
StudentInfoTool.writeToFile(stus);
}
}
classStudent implements Comparable<Student>
{
private String name;
private int ma,cn,en;
private int sum;
Student(String name,int ma,int cn,inten)
{
this.name=name;
this.ma=ma;
this.cn=cn;
this.en=en;
sum=ma+cn+en;
}
public int compareTo(Student s)
{
int num=newInteger(this.sum).compareTo(new Integer(s.sum));
if(num==0)
returnthis.name.compareTo(s.name);
return num;
}
public String getName()
{
return name;
}
public int getSum()
{
return sum;
}
public int hashCode()
{
returnname.hashCode()+sum*78;
}
public boolean equals(Object obj)
{
if(!(obj instanceof Student))
throw newClassCastException("类型不配");
Student s=(Student)obj;
returnthis.name.equals(s.name)&&this.sum==s.sum;
}
public String toString()
{
return"Student["+name+","+ma+","+cn+","+en+"]";
}
}
classStudentInfoTool
{
public static Set<Student>getStudents()throws IOException
{
return getStudents(null);
}
public static Set<Student>getStudents(Comparator<Student> cmp)throws IOException
{
BufferedReader bufr=newBufferedReader(new InputStreamReader(System.in));
String line=null;
Set<Student> stus=null;
if(cmp==null)
stus=newTreeSet<Student>();
else
stus=newTreeSet<Student>(cmp);
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
String[]info=line.split(",");
Student stu=newStudent(info[0],Integer.parseInt(info[1]),
Integer.parseInt(info[2]),
Integer.parseInt(info[3]));
stus.add(stu);
}
bufr.close();
return stus;
}
public static voidwriteToFile(Set<Student> stus)throws IOException
{
BufferedWriter bufw=newBufferedWriter(new FileWriter("stud.txt"));
for(Student stu:stus)
{
bufw.write(stu.toString()+"\t");
bufw.write(stu.getSum()+"");
bufw.newLine();
bufw.flush();
}
bufw.close();
}
}