Java 进阶知识(二)

28 阅读11分钟

File API

package file;

import java.io.File;

/**
 * java.io.File
 * File的每一个实例用于表示硬盘上的一个文件或
 * 目录。
 * 使用File可以:
 * 1:访问其表示的文件或目录的属性信息(名字,大
 *   小,访问权限等信息)
 * 2:操作文件或目录(创建,删除)  
 * 3:访问目录子项
 * 但是不能访问文件数据。
 * @author ta
 *
 */
public class FileDemo {
	public static void main(String[] args) {
		/*
		 * 访问当前项目目录下的test.txt文件
		 * 
		 * 创建File时,指定的路径通常使用相对
		 * 路径,好处在于:可以跨平台。
		 * 相对路径到底相对哪里,要看程序的
		 * 运行环境指定的位置。
		 * 在eclipse中运行java程序时,指定的
		 * 相对路径中"当前目录"是当前程序所在
		 * 的项目目录,这里就是JSD1807_SE这个
		 * 目录
		 */
		File file = new File("./test.txt");
		
		String name = file.getName();
		System.out.println("name:"+name);
		
		//获取文件大小(字节量)
		long length = file.length();
		System.out.println("length:"+length);
	
		boolean cw = file.canWrite();
		boolean cr = file.canRead();
		System.out.println("可写:"+cw);
		System.out.println("可读:"+cr);
		
		boolean ih = file.isHidden();
		System.out.println("隐藏:"+ih);
	}
}
package file;

import java.io.File;

/**
 * 删除一个文件
 * @author ta
 *
 */
public class DeleteFileDemo {
	public static void main(String[] args) {
		/*
		 * 将当前目录下的demo.txt文件删除
		 */
		File file = new File("./demo.txt");
		if(file.exists()) {
			file.delete();
			System.out.println("文件已删除");
		}else {
			System.out.println("文件不存在");
		}
	}
}
package file;

import java.io.File;

/**
 * 创建一个目录
 * @author ta
 *
 */
public class MkDirDemo {
	public static void main(String[] args) {
		/*
		 * 在当前目录中创建一个名为demo的目录
		 */
		File dir = new File("./demo");
		if(!dir.exists()) {
			dir.mkdir();
			System.out.println("目录已创建");
		}else {
			System.out.println("目录已存在");
		}
	}
}
package file;

import java.io.File;

/**
 * 创建一个多级目录
 * @author ta
 *
 */
public class MkDirsDemo {
	public static void main(String[] args) {
		/*
		 * 在当前目录下创建:
		 * a/b/c/d/e/f目录
		 */
		File dir = new File("./a/b/c/d/e/f");
		if(!dir.exists()) {
			/*
			 * mkdir创建目录要求父目录必须存在
			 * mkdirs会将不存在的父目录一同的
			 * 创建出来
			 */
			dir.mkdirs();
			System.out.println("创建完毕!");
		}else {
			System.out.println("目录已存在!");
		}
	}
}
package file;

import java.io.File;

/**
 * 删除目录
 * @author ta
 *
 */
public class DeleteDirDemo {
	public static void main(String[] args) {
		/*
		 * 删除当前目录下的demo目录
		 */
		File dir = new File("./demo");
		if(dir.exists()) {
			/*
			 * 删除目录要求该目录必须是一个
			 * 空目录。
			 */
			dir.delete();
			System.out.println("删除完毕!");
		}else {
			System.out.println("目录不存在!");
		}
	}
}
package file;

import java.io.File;

/**
 * 获取一个目录中的所有子项
 * @author ta
 *
 */
public class ListFilesDemo {
	public static void main(String[] args) {
		/*
		 * 获取当前目录中的所有子项
		 */
		File dir = new File(".");
		/*
		 * boolean isFile()
		 * boolean isDirectory()
		 * 判断当前File对象表示的是一个文件
		 * 还是一个目录
		 */
		if(dir.isDirectory()) {
			/*
			 * File[] listFiles()
			 * 该方法会将当前File表示的目录中所有
			 * 子项返回.
			 */
			File[] subs = dir.listFiles();
			for(int i=0;i<subs.length;i++) {
				File sub = subs[i];
				System.out.println(sub.getName());
			}
		}

	}
}
package file;

import java.io.File;

/**
 * 完成方法,实现删除给定File所表示的文件或目录
 * @author ta
 *
 */
public class Test {
	public static void main(String[] args) {
		File dir = new File("./a");
		delete(dir);
	}
	/**
	 * 文件直接删除,目录的话要先清空该目录
	 * 然后再删除
	 * @param f
	 */
	public static void delete(File f) {
		if(f.isDirectory()) {
			//先清空该目录
			File[] subs = f.listFiles();
			for(int i=0;i<subs.length;i++) {
				File sub = subs[i];
				//递归调用
				delete(sub);
			}
		}
		f.delete();
	}
}
package file;

import java.io.File;
import java.io.FileFilter;

/**
 * ListFiles提供了一个重载的方法,可以指定
 * 一个文件过滤器(FileFilter),然后将满足该
 * 过滤器要求的子项返回。
 * @author ta
 *
 */
public class ListFilesDemo2 {
	public static void main(String[] args) {
		/*
		 * 获取当前目录中名字以"."开头的子项
		 */
		File dir = new File(".");
		
		FileFilter filter = new FileFilter() {
			public boolean accept(File file) {
				String name = file.getName();
				System.out.println("正在过滤:"+name);
				return name.startsWith(".");
			}		
		};
		
		File[] subs = dir.listFiles(filter);
		System.out.println(subs.length);
		for(int i=0;i<subs.length;i++) {
			System.out.println(subs[i].getName());
		}
	}
}
package file;

import java.io.File;
import java.io.IOException;

/**
 * 使用File创建一个文件
 * @author ta
 *
 */
public class CreateNewFileDemo {
	public static void main(String[] args) throws IOException {
		/*
		 * 在当前目录下创建一个名为:demo.txt
		 * 的文件
		 */
		File file = new File("./demo.txt");
		if(!file.exists()) {
			file.createNewFile();
			System.out.println("文件已创建");
		}else {
			System.out.println("文件已存在");
		}
	}
}

RandomAccessFile API

package raf;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * java.io.RandomAccessFile
 * RAF是专门用来读写文件数据的API。其基于指针
 * 对文件数据进行读写操作,可以灵活的编辑文件
 * 数据内容。
 * 创建RAF时可以指定对该文件的权限,常用的有
 * 两种:
 * r:只读模式
 * rw:读写模式 
 * @author ta
 *
 */
public class RafDemo {
	public static void main(String[] args) throws IOException {
		/*
		 * 对当前目录中的raf.dat文件读写
		 * RAF支持两种常用构造方法:
		 * RandomAccessFile(File file,String mode)
		 * RandomAccessFile(String path,String mode)
		 * 
		 * 注:相对路径中"./"是可以忽略不写的,因为
		 * 默认就是从当前目录开始。
		 * 
		 * RAF创建时含有写权限的情况下,当指定的文件
		 * 不存在时会自动将其创建出来。
		 */
		RandomAccessFile raf
			= new RandomAccessFile("raf.dat","rw");
		/*
		 * void write(int d)
		 * 向文件中写入1字节,写的是给定int值
		 * 对应2进制的“低八位”                 
		 *                            vvvvvvvv                               
		 * 00000000 00000000 00000000 00000001
		 * 11111111 11111111 11111111 11111111
		 * 
		 */
		raf.write(1);
		
		System.out.println("写出完毕!");
		
		raf.close();
	}
}
package raf;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 读取文件数据
 * @author ta
 *
 */
public class ReadDemo {
	public static void main(String[] args) throws IOException {
		/*
		 * 读取当前目录中raf.dat文件内容
		 */
		RandomAccessFile raf
			= new RandomAccessFile("raf.dat","r");
		/*
		 * int read()
		 * 读取一个字节,并以int形式返回。
		 * 若返回值为-1则表示读取到了文件末尾。
		 * 00000000 00000000 00000000 00000001
		 */
		int d = raf.read();
		System.out.println(d);
		
		d = raf.read();
		System.out.println(d);//-1
		raf.close();
	}
}
package raf;

import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 复制文件操作
 * @author ta
 *
 */
public class CopyDemo {
	public static void main(String[] args) throws IOException {
		/*
		 * 创建两个RAF,一个用来读原文件,
		 * 一个用来往复制文件中写。
		 * 顺序从原文件读取每个字节写入到
		 * 复制文件中。
		 */
		RandomAccessFile src
			= new RandomAccessFile("movie.wmv","r");
		
		RandomAccessFile desc
			= new RandomAccessFile("movie_cp.wmv","rw");
		//记录每次读取到的字节
		int d = -1;
		while((d = src.read())!=-1) {
			desc.write(d);
		}
		System.out.println("复制完毕!");
		src.close();
		desc.close();
		
	}
}
package raf;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 若希望提高读写效率,可以通过提高每次实际读写
 * 的数据量,减少实际发生的读写操作来做到。
 * 单字节读写:随机读写
 * 一组字节读写:块读写
 * 机械硬盘(磁盘)的块读写效率还是比较好的。但是
 * 随机读写效率极差。
 * @author ta
 *
 */
public class CopyDemo2 {
	public static void main(String[] args) throws IOException {
		RandomAccessFile src
			= new RandomAccessFile("nox.exe","r");
		RandomAccessFile desc
			= new RandomAccessFile("nox_cp.exe","rw");
		
		/*
		 * RAF提供的块读写操作的方法:
		 * int read(byte[] data)
		 * 一次性读取给定的字节数组长度的字节
		 * 量并存入到该数组中。返回值为实际
		 * 读取到的字节量,若返回值为-1,表示
		 * 本次读取是文件末尾(没读到任何字节)
		 * 
		 * void write(byte[] data)
		 * 一次性写出给定字节数组中的所有字节
		 * 
		 * void write(byte[] data,int start,int len)
		 * 一次性写出给定字节数组中从start处开始的连续
		 * len个字节
		 */
		//记录每次实际读取到的字节量
		int len = -1;
		//每次要求读取的字节量
		//10kb
		byte[] data = new byte[1024*10];
		
		long start = System.currentTimeMillis();
		while((len = src.read(data))!=-1) {
			desc.write(data,0,len);
		}
		long end= System.currentTimeMillis();
		System.out.println("复制完毕!耗时"+(end-start)+"ms");
		src.close();
		desc.close();
	}
}
package raf;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 写出字符串操作
 * @author ta
 *
 */
public class WriteStringDemo {
	public static void main(String[] args) throws IOException {
		RandomAccessFile raf = new RandomAccessFile("raf.txt","rw");
		String line = "大家好,我是渣渣辉。";
		/*
		 * String提供了转换为2进制的方法:
		 * byte[] getBytes();
		 */
//		byte[] data = line.getBytes();
		//可以指定字符集进行转换(推荐这样的用法)
		byte[] data = line.getBytes("UTF-8");	
		raf.write(data);	
		System.out.println("写出完毕");
		raf.close();
		
	}
}
package raf;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 读取字符串
 * @author ta
 *
 */
public class ReadStringDemo {
	public static void main(String[] args) throws IOException {
		/*
		 * 将raf.txt文件中的字符读取出来
		 */
		RandomAccessFile raf = new RandomAccessFile("raf.txt","r");
		
		byte[] data = new byte[(int)raf.length()];
		raf.read(data);
		
		String str = new String(data,"UTF-8");
		System.out.println(str);
		
		raf.close();
		
	}
}
package raf;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Scanner;

/**
 * 完成简易记事本工具
 * 程序启动后,要求用户输入文件名,然后使用
 * RAF对该文件读写操作。
 * 之后用户在控制台输入的每行字符串都写入到
 * 该文件中。
 * 当用户输入了“exit”时,程序退出。
 * 
 * @author ta
 *
 */
public class Test {
	public static void main(String[] args) throws IOException {
		Scanner scanner = new Scanner(System.in);
		System.out.println("请输入文件名:");
		String fileName = scanner.nextLine();		
		RandomAccessFile raf
			= new RandomAccessFile(fileName,"rw");
		System.out.println("请开始输入内容:");
		String line = "";
		while(true) {
			line = scanner.nextLine();
			if("exit".equals(line)) {
				break;
			}
			raf.write(line.getBytes("UTF-8"));
		}
		System.out.println("再见!");
		raf.close();
	}
}
package raf;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * RAF读写基本类型数据,以及RAF的指针操作
 * @author ta
 *
 */
public class RafDemo2 {
	public static void main(String[] args) throws IOException {
		RandomAccessFile raf
			= new RandomAccessFile("raf.dat","rw");
		
		long pos = raf.getFilePointer();
		System.out.println("pos:"+pos);
		
		
		//写入一个int最大值到文件中
		int max = Integer.MAX_VALUE;
		/*
		 * int最大值的2进制形式:
		 *                            vvvvvvvv
		 * 01111111 11111111 11111111 11111111
		 * 
		 * max>>>24                            v这里开始溢出了
		 * 00000000 00000000 00000000 01111111 11111111 11111111 11111111
		 */
		raf.write(max>>>24);
		System.out.println("pos:"+raf.getFilePointer());
		raf.write(max>>>16);
		raf.write(max>>>8);
		raf.write(max);
		System.out.println("pos:"+raf.getFilePointer());
		/*
		 * void writeInt(int d)
		 * 连续写出4个字节,将给定的int值写出。
		 * 等同上面4次write方法。
		 */
		raf.writeInt(max);
		System.out.println("pos:"+raf.getFilePointer());
		raf.writeLong(123L);
		System.out.println("pos:"+raf.getFilePointer());
		raf.writeDouble(123.123);
		System.out.println("pos:"+raf.getFilePointer());
		System.out.println("写出完毕!");
		
		//写完后指针现在在文件末尾
		
		//移动指针位置
		raf.seek(0);//移动到文件开始位置
		System.out.println("pos:"+raf.getFilePointer());
		//连续读取4字节还原int值
		int d = raf.readInt();
		System.out.println(d);
		System.out.println("pos:"+raf.getFilePointer());
		
		//读取long
		raf.seek(8);
		System.out.println("pos:"+raf.getFilePointer());
		long l = raf.readLong();
		System.out.println(l);//123
		System.out.println("pos:"+raf.getFilePointer());
		
		double dou = raf.readDouble();
		System.out.println(dou);//123.123
		System.out.println("pos:"+raf.getFilePointer());
		
		
		raf.close();
	}
}
package raf;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays;
import java.util.Scanner;

/**
 * 完成用户注册功能
 * 
 * 程序开始后,要求用户输入:
 * 用户名,密码,昵称,年龄
 * 
 * 将该记录写入到user.dat文件中。
 * 其中用户名,密码,昵称为字符串。年龄为
 * 一个int值。
 * 
 * 每条记录占用100字节,其中:用户名,密码,
 * 昵称为字符串,各占32字节,年龄为int占用
 * 4字节。
 * 
 * 
 * @author ta
 *
 */
public class RegDemo {
	public static void main(String[] args) throws IOException {
		System.out.println("欢迎注册");
		Scanner scanner = new Scanner(System.in);
		
		System.out.println("请输入用户名:");
		String username = scanner.nextLine();
		
		System.out.println("请输入密码:");
		String password = scanner.nextLine();
		
		System.out.println("请输入昵称:");
		String nickname = scanner.nextLine();
		
		System.out.println("请输入年龄:");
		int age = Integer.parseInt(scanner.nextLine());
		
		System.out.println(username+","+password+","+nickname+","+age);
		
		RandomAccessFile raf
			= new RandomAccessFile("user.dat","rw");
		//现将指针移动到文件末尾
		raf.seek(raf.length());
		
		
		//写用户名
		//1先将用户名转成对应的一组字节
		byte[] data = username.getBytes("UTF-8");
		//2将该数组扩容为32字节
		data = Arrays.copyOf(data, 32);
		//3将该字节数组一次性写入文件
		raf.write(data);
		
		//写密码
		data = password.getBytes("UTF-8");
		data = Arrays.copyOf(data, 32);
		raf.write(data);
		
		//写昵称
		data = nickname.getBytes("UTF-8");
		data = Arrays.copyOf(data, 32);
		raf.write(data);
		
		//写年龄
		raf.writeInt(age);
		
		System.out.println("注册完毕!");
		raf.close();
	}
}
package raf;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * java.io.RandomAccessFile
 * RAF是专门用来读写文件数据的API。其基于指针
 * 对文件数据进行读写操作,可以灵活的编辑文件
 * 数据内容。
 * 创建RAF时可以指定对该文件的权限,常用的有
 * 两种:
 * r:只读模式
 * rw:读写模式 
 * @author ta
 *
 */
public class RafDemo {
	public static void main(String[] args) throws IOException {
		/*
		 * 对当前目录中的raf.dat文件读写
		 * RAF支持两种常用构造方法:
		 * RandomAccessFile(File file,String mode)
		 * RandomAccessFile(String path,String mode)
		 * 
		 * 注:相对路径中"./"是可以忽略不写的,因为
		 * 默认就是从当前目录开始。
		 * 
		 * RAF创建时含有写权限的情况下,当指定的文件
		 * 不存在时会自动将其创建出来。
		 */
		RandomAccessFile raf
			= new RandomAccessFile("raf.dat","rw");
		/*
		 * void write(int d)
		 * 向文件中写入1字节,写的是给定int值
		 * 对应2进制的“低八位”                 
		 *                            vvvvvvvv                               
		 * 00000000 00000000 00000000 00000001
		 * 11111111 11111111 11111111 11111111
		 * 
		 */
		raf.write(1);
		
		System.out.println("写出完毕!");
		
		raf.close();
	}
}
package raf;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 读取文件数据
 * @author ta
 *
 */
public class ReadDemo {
	public static void main(String[] args) throws IOException {
		/*
		 * 读取当前目录中raf.dat文件内容
		 */
		RandomAccessFile raf
			= new RandomAccessFile("raf.dat","r");
		/*
		 * int read()
		 * 读取一个字节,并以int形式返回。
		 * 若返回值为-1则表示读取到了文件末尾。
		 * 00000000 00000000 00000000 00000001
		 */
		int d = raf.read();
		System.out.println(d);
		
		d = raf.read();
		System.out.println(d);//-1
		raf.close();
	}
}
package raf;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays;
import java.util.Scanner;

/**
 * 修改昵称
 * 
 * 程序启动后,要求用户输入要修改昵称的用户名
 * 以及新的昵称。然后将该用户昵称进行修改操作
 * 若输入的用户名不存在,则提示"无此用户"。
 * @author ta
 *
 */
public class UpdateDemo {
	public static void main(String[] args) throws IOException {
		/*
		 * 1:获取用户输入的用户名及新昵称
		 * 2:使用RAF打开user.dat文件
		 * 3:循环读取每条记录
		 *   3.1:将指针移动到该条记录用户名
		 *       的位置(i*100)
		 *   3.2:读取32字节,将用户名读取出来
		 *   3.3:判断该用户是否为用户输入的用户
		 *   3.4:若是此人,则移动指针到该条
		 *       记录昵称位置,将新昵称以32字节        
		 *       写入该位置,覆盖原昵称完成修改
		 *       并停止循环操作。
		 *   3.5:若不是此人则进入下次循环    
		 * 
		 * 可以添加一个开关,当修改过昵称后,改变
		 * 其值,最终在循环完毕后,根据开关的值判定
		 * 是否有修改信息来输出"无此用户"
		 * 
		 */
		Scanner scanner = new Scanner(System.in);
		System.out.println("请输入用户名:");
		String username = scanner.nextLine();
		
		System.out.println("请输入新的昵称:");
		String nickname = scanner.nextLine();
		
		RandomAccessFile raf
			= new RandomAccessFile("user.dat","rw");
		//开关,表示是否有修改过信息
		boolean update = false;
		for(int i=0;i<raf.length()/100;i++) {
			//先将指针移动到该条记录的开始位置
			raf.seek(i*100);
			//读取用户名
			byte[] data = new byte[32];
			raf.read(data);
			String name = new String(data,"UTF-8").trim();
			if(name.equals(username)) {
				//修改昵称
				//1先移动指针到昵称的位置
				raf.seek(i*100+64);
				//2重新写昵称32字节
				data = nickname.getBytes("UTF-8");
				data = Arrays.copyOf(data, 32);
				raf.write(data);
				System.out.println("修改完毕!");
				update = true;
				break;
			}
		}
		if(!update) {
			System.out.println("无此用户!");
		}
		raf.close();
	}
}
package raf;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 显示所有注册用户信息
 * @author ta
 *
 */
public class ShowAllUserDemo {
	public static void main(String[] args) throws IOException {
		RandomAccessFile raf
			= new RandomAccessFile("user.dat","r");
		/*
		 * 循环读取若干个100字节
		 */
		for(int i=0;i<raf.length()/100;i++) {		
			//读用户名
			//1先读取32字节
			byte[] data = new byte[32];
			raf.read(data);
			//2将字节数组转换为字符串
			String username = new String(data,"UTF-8").trim();
			
			//读取密码
			raf.read(data);
			String password = new String(data,"UTF-8").trim();
			
			//读昵称
			raf.read(data);
			String nickname = new String(data,"UTF-8").trim();
			
			//读年龄
			int age = raf.readInt();
			System.out.println(username+","+password+","+nickname+","+age);
			
		}
		
		raf.close();
	}
}