File的常见操作:File(String pathname) File(File path String child)
创建:
createNewFile():创建文件,在指定位置只能创建一次,不会覆盖,返回boolean
mkdir():创建目录,一次只能创建一层目录,返回boolean
mkdirs():创建多层目录,返回boolean
判断、删除:
delete():删除文件,返回boolean。
deleteOnExit():退出程序时删除。
canExecute():是否是可执行文件。返回boolean
exists():文件是否存在,返回boolean
isFile():是否是一个标准文件。返回boolean。当判断是不是一个文件或者目录的时候首先要判断这个目录或文件是否存在,用exists()。
isDirectory():判断是否是一个目录。返回boolean
isAbsolute():判断是不是绝对路径。返回boolean
lastModified():返回左后一次修改的时间值long,可以通过判断时间的相同判断是否被修改过。
获取:
getName():
getPath():
getParent():
getAbsolutePath():
getAbsolutePathFile():把绝对路径封装成对象返回
renameTo(File dest):如果两个对象在不同目录想相当于剪切
listRoots():列出可用的文件系统根。
list():
public static void listRootsDemo() {
File[] files = File.listRoots(); //这个方法是个静态方法,返回的是
for(File f : files) {
System.out.println(f);
}
}
public static void main(String[] args) {
File dir = new File("c:\\");
File[] files = dir.listFiles();
for(File f : files) {
System.out.println(f.getName()+"::"+f.length());
}
}
public static void listDemo() {
File dir = new File("d:\\program\\java");
String[] arr = dir.list(new FilenameFilter() //返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录。
{
public boolean accept(File dir,String name) {
//System.out.println("dir:"+dir+"....name::"+name);
/* if(name.endsWith(".bmp"))
return true;
else
return false; */
return name.endsWith(".bmp");
}
});
System.out.println("len:"+arr.length);
for(String name : arr) {
System.out.println(name);
}
}
public static void listDemo() {
File f = new File("c:\\abc.txt");
String[] names = f.list();//调用list方法的file对象必须是封装了一个目录。该目录还必须存在。
for(String name : names) {
System.out.println(name);
}
}
递归:在一个函数里自己调用自己,注意:1,限定条件。2,要注意递归的次数。尽量避免内存溢出。
public static void showDir(File dir,int level) {
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]);
}
}
Properties:是集合中和IO技术相结合的集合容器。该对象的特点:可以用于键值对形式的配置文件。
限制程序运行次数。当运行次数到达5次时,给出,请您注册的提示。并不再让该程序执行。
import java.io.*;
import java.util.*;
class RunCount {
public static void main(String[] args) throws IOException {
Properties prop = new Properties();
File file = new File("count.ini");
if(!file.exists()) //判断文件是否存在
file.createNewFile(); 不存在创建这个文件
FileInputStream fis = new FileInputStream(file);输入流
prop.load(fis); //每次启动软件的时候自动导入文件信息
int count = 0;
String value = prop.getProperty("time"); //并获得次数的信息
if(value!=null) {
count = Integer.parseInt(value);
if(count>=5) {
System.out.println("您好,使用次数已到,拿钱!");
return ;
}
}
count++;
prop.setProperty("time",count+""); //运行重新将信息添加到集合中
FileOutputStream fos = new FileOutputStream(file); //输出流,
prop.store(fos,""); //将输出流写入到文件中 两个参数分别为输出流和注释信息
fos.close();
fis.close();
}
}
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
import java.io.*;
import java.util.*;
class PropertiesDemo {
public static void main(String[] args) throws IOException {
//method_1();
loadDemo(); }
public static void loadDemo()throws IOException {
Properties prop = new Properties();
FileInputStream fis = new FileInputStream("info.txt");
//将流中的数据加载进集合。
prop.load(fis);
prop.setProperty("wangwu","39");
FileOutputStream fos = new FileOutputStream("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()throws IOException {
BufferedReader bufr = new BufferedReader(new FileReader("info.txt"));
String line = null;
Properties prop = new Properties();
while((line=bufr.readLine())!=null) {
String[] arr = line.split("=");
//System.out.println(arr[0]+"...."+arr[1]);
prop.setProperty(arr[0],arr[1]);
}
bufr.close();
System.out.println(prop);
}
// 设置和获取元素。
public static void setAndGet() {
Properties prop = new Properties();
prop.setProperty("zhangsan","30");
prop.setProperty("lisi","39");
// System.out.println(prop);
String value = prop.getProperty("lisi");
//System.out.println(value);
prop.setProperty("lisi",89+"");
Set<String> names = prop.stringPropertyNames();
for(String s : names) {
System.out.println(s+":"+prop.getProperty(s));
}
}
}
合并流:SequenceInputStream(Enumeration<? extends InputStream> e),从这个构造函数可以看出,它可以接收字节输入流及其子类的枚举类型的参数,在集合体系
中只有vector可以获取枚举
import java.io.*;
import java.util.*;
class SequenceDemo {
public static void main(String[] args) throws IOException {
Vector<FileInputStream> v = new Vector<FileInputStream>();
v.add(new FileInputStream("c:\\1.txt"));
v.add(new FileInputStream("c:\\2.txt"));
v.add(new FileInputStream("c:\\3.txt"));
Enumeration<FileInputStream> en = v.elements(); //返回此向量的组件的枚举。
SequenceInputStream sis = new SequenceInputStream(en); //源
FileOutputStream fos = new FileOutputStream("c:\\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();
}
}
切割流:这个多看看
import java.io.*;
import java.util.*;
class SplitFile {
public static void main(String[] args) throws IOException {
splitFile(); //切割
merge(); //合并
}
public static void merge()throws IOException {
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
for(int x=1; x<=3; x++) {
al.add(new FileInputStream("c:\\splitfiles\\"+x+".part"));
}
final Iterator<FileInputStream> it = al.iterator();
Enumeration<FileInputStream> en = new Enumeration<FileInputStream>()
{
public boolean hasMoreElements() { //复写了Enumeration接口的两个方法
return it.hasNext();
}
public FileInputStream nextElement() {
return it.next();
}
};
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream("c:\\splitfiles\\0.bmp");
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()throws IOException {
FileInputStream fis = new FileInputStream("c:\\1.bmp");
FileOutputStream fos = null;
byte[] buf = new byte[1024*1024];
int len = 0;
int count = 1;
while((len=fis.read(buf))!=-1) {
fos = new FileOutputStream("c:\\splitfiles\\"+(count++)+".part");
fos.write(buf,0,len);
fos.close();
}
fis.close();
}
}
打印字节流:PrintStream
构造函数可以接收的参数类型:
1,file对象。File
2,字符串路径。String
3,字节输出流。OutputStream
打印字符流:PrintWriter
1,file对象。File
2,字符串路径。String
3,字节输出流。OutputStream
4,字符输出流,Writer。
import java.io.*;
class PrintStreamDemo {
public static void main(String[] args) throws IOException {
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(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();
}
}
对象的持久化(序列化、可串行性)将内存中的对象存储到硬盘上,要想被序列化要实现seriallzable接口,序列化的时候就是给对象加一个UID号,对象的序列化就是依赖于
这个Uid.
import java.io.*;
class Person implements Serializable {
public static final long serialVersionUID = 42L; //自定义一个序列号再次编译的时候也不会出错
private String name;
transient int age; //加上transient关键字age就可以不被序列化,始终将对象保存于堆内存中。
static String country = "cn"; //静态成员不能被序列化,调用构造函数输入后country即使被修改为kr但是输出还是CH
Person(String name,int age,String country) {
this.name = name;
this.age = age;
this.country = country;
}
public String toString() {
return name+":"+age+":"+country;
}
}
import java.io.*;
class ObjectStreamDemo {
public static void main(String[] args) throws Exception {
writeObj();
readObj();
}
public static void readObj()throws Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));
Person p = (Person)ois.readObject();
System.out.println(p);
ois.close();
}
public static void writeObj()throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));
oos.writeObject(new Person("lisi0",399,"kr"));
oos.close();
}
}
管道流:
pipedInputStream pipedOutputStream
import java.io.*;
class Read implements Runnable {
private PipedInputStream in;
Read(PipedInputStream in) {
this.in = in;
}
public void run() {
try {
byte[] buf = new byte[1024];
System.out.println("读取前。。没有数据阻塞");
int len = in.read(buf);
System.out.println("读到数据。。阻塞结束");
String s= new String(buf,0,len);
System.out.println(s);
in.close();
}
catch (IOException e) {
throw new RuntimeException("管道读取流失败");
}
}
}
class Write implements Runnable {
private PipedOutputStream out;
Write(PipedOutputStream out) {
this.out = out;
}
public void run() {
try {
System.out.println("开始写入数据,等待6秒后。");
Thread.sleep(6000);
out.write("piped lai la".getBytes());
out.close();
}
catch (Exception e) {
throw new RuntimeException("管道输出流失败");
}
}
}
class PipedStreamDemo {
public static void main(String[] args) throws IOException {
PipedInputStream in = new PipedInputStream();
PipedOutputStream out = new PipedOutputStream();
in.connect(out);
Read r = new Read(in);
Write w = new Write(out);
new Thread(r).start();
new Thread(w).start();
}
}
RandomAccessFile:该类不是IO体系中子类,它直接继承Object,自身具有读和写的功能,操作这个流时还有四种模式,r,rw,rws,rwd。内部封装了一个大型的字节数
组,而且通过指针对数组的元素进行操作,这个类操作的对象存储数据最好是有序的读出来才是有效的呢!!
class RandomAccessFileDemo {
public static void main(String[] args) throws IOException {
//writeFile_2();
//readFile();
//System.out.println(Integer.toBinaryString(258));
}
public static void readFile()throws IOException {
RandomAccessFile raf = new RandomAccessFile("ran.txt","r");
raf.seek(8*1); //调整对象中指针。
raf.skipBytes(8); //跳过指定的字节数 ,可以从8以后读取,但是只能向前跳过 0》》》.......
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 writeFile_2()throws IOException {
RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");
raf.seek(8*0); //设置指针偏移量,可以从数组的任意位置读取
raf.write("周七".getBytes()); //内部封装的是字节数组,可以随机修改:把raf.seek(8*0); 修改成raf.write("周七".getBytes());
raf.writeInt(103); //这个方法可以把4个8位全写了,避免了write()方法的只写最后8位造成的数据丢失
raf.close();
}
public static void writeFile()throws IOException {
RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");
raf.write("李四".getBytes());
raf.writeInt(97);
raf.write("王五".getBytes());
raf.writeInt(99);
raf.close();
}
}
可以操作基本数据类型的数组流对象:DataInputStream DataOutputStream
writeUTF()和readUTF()要对应的读写。
用于操作字节数组的流对象:因为这两个流对象都操作的数组,并没有使用系统资源。所以,不用进行close关闭。
ByteArrayInputStream :在构造的时候,需要接收数据源,。而且数据源是一个字节数组
ByteArrayOutputStream: 在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组。这就是数据目的地。
import java.io.*;
class ByteArrayStream {
public static void main(String[] args) {
ByteArrayInputStream bis = new ByteArrayInputStream("ABCDEFD".getBytes()); //数据源
ByteArrayOutputStream bos = new ByteArrayOutputStream(); //数据目的
int by = 0;
while((by=bis.read())!=-1) {
bos.write(by);
}
System.out.println(bos.size());
System.out.println(bos.toString());
// bos.writeTo(new FileOutputStream("a.txt"));
}
}
编码问题的产生与解决
GBK和Unicode都能识别中文,那么当一台电脑使用GBK,而另一台电脑使用Unicode时,虽然在各自的电脑上都能识别中文,但他们其中一方向另一方发送中文文字时,另一方却不能识别,出现了乱码。这是因为GBK和Unicode虽然都能识别中文,但对同一个中文文字,他们在两个编码表对应的编码值不同。这时,在解读别人传来的中文数据时,就需要指定解析中文使用的编码表了。而转换流就能指定编码表,它的应用可以分为:
1. 可以将字符以指定的编码格式存储。
2. 可以对文本数据以指定的编码格式进行解读。
它们指定编码表的动作是由构造函数完成的。
编码:字符串变成字节数组。
解码:字节数组变成字符串。
编码编错:
是指你对一个文字进行编码时,使用了不识别该文字的编码表,比如你编码一个汉字,却使用了ISO8859-1这个拉丁码表,ISO8859-1根本就不识别汉字。编码编错时,你用任何方式对编码后的数据进行处理,都不可能再拿到这个汉字了。
解码解错:
是指你对一个文字进行编码事,使用了正确的码表,编码正确,但在解码时使用了错误的码表,那么你还有可能拿到这个文字。这分为两种情况:
第一种情况:
你使用的是GBK编码,解码时用的是ISO8859-1,因为GBK编译一个汉字,使用两个字节,ISO8859-1解码时是一个字节一个字节读取,虽然解码出现了乱码,但是这个汉字的二进制数据没有变化,那么你可以通过再次编译获取其原来的二进制数据,然后再次使用GBK编码,解码成功。
第二种情况:
你使用的是GBK编码,解码时用的却是UTF-8,因为这两个码表都识别汉字,那么你再次使用UTF-8编码时,就有可能把一个汉字的2个字节,变成3个,这时再用GBK解码时,得到的仍然是乱码,解码仍然失败。
有五个学生,每个学生有3门课的成绩, 从键盘输入以上数据(包括姓名,三门课成绩), 输入的格式:如:zhagnsan,30,40,60计算出总成绩, 并把学生的信息和计
算出的总分数高低顺序存放在磁盘文件"stud.txt"中。
1,描述学生对象。
2,定义一个可操作学生对象的工具类。
思想: 1,通过获取键盘录入一行数据,并将该行中的信息取出封装成学生对象。 2,因为学生有很多,那么就需要存储,使用到集合。因为要对学生的总分排序。 所以可以使用TreeSet。 3,将集合的信息写入到一个文件中。
*/
import java.io.*;
import java.util.*;
class Student implements Comparable<Student> { //让学生具有自己的比较性,实现了接口Comparable
private String name;
private int ma,cn,en;
private int sum;
Student(String name,int ma,int cn,int en) {
this.name = name;
this.ma = ma;
this.cn = cn;
this.en = en;
sum = ma + cn + en;
}
public int compareTo(Student s) {
int num = new Integer(this.sum).compareTo(new Integer(s.sum));
if(num==0)
return this.name.compareTo(s.name);
return num;
}
public String getName() {
return name;
}
public int getSum() {
return sum;
}
public int hashCode() {
return name.hashCode()+sum*78;
}
public boolean equals(Object obj) {
if(!(obj instanceof Student))
throw new ClassCastException("类型不匹配");
Student s = (Student)obj;
return this.name.equals(s.name) && this.sum==s.sum;
}
public String toString() {
return "student["+name+", "+ma+", "+cn+", "+en+"]";
}
}
class StudentInfoTool {
public static Set<Student> getStudents()throws IOException {
return getStudents(null);
}
public static Set<Student> getStudents(Comparator<Student> cmp)throws IOException {
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
String line = null;
Set<Student> stus = null;
if(cmp==null)
stus = new TreeSet<Student>();
else
stus = new TreeSet<Student>(cmp);
while((line=bufr.readLine())!=null) {
if("over".equals(line))
break;
String[] info = line.split(",");
Student stu = new Student(info[0],Integer.parseInt(info[1]),
Integer.parseInt(info[2]),
Integer.parseInt(info[3]));
stus.add(stu);
}
bufr.close();
return stus;
}
public static void write2File(Set<Student> stus)throws IOException {
BufferedWriter bufw = new BufferedWriter(new FileWriter("stuinfo.txt"));
for(Student stu : stus) {
bufw.write(stu.toString()+"\t");
bufw.write(stu.getSum()+"");
bufw.newLine();
bufw.flush();
}
bufw.close();
}
}
class StudentInfoTest {
public static void main(String[] args) throws IOException {
Comparator<Student> cmp = Collections.reverseOrder();
Set<Student> stus = StudentInfoTool.getStudents(cmp);
StudentInfoTool.write2File(stus);
}
}