IO知识梳理2
---------------------------------------------------------------------------------------------------------------------------------------------
1、File 重点方法
listRoots():列出 系统的盘符。String list() :列出该盘符下所有的文件夹、文件 保过隐藏部分。list(FilenameFilter filter): 文件过滤,选出指定文件File listFiles() :比list()更常用,因为被封装为对象,所以可以获取其名字和长度
2、递归 函数自身调用自身。
3、递归注意事项:这种表现形式,或者说编程手法,称为【递归。【函数自身调用自身。】】
1、限定条件。
2、要注意递归的次数,尽量避免内存溢出。
4、Properties 是 hashtable 的子类
也就是说它具备 map 集合的特点,而且他里面存储的【键值对】 都是字符串
5、打印流 : 可以直接操作输入流和文件。
PrintStreamPrintWriter该流提供了打印方法,可以将各种数据类型的数据都原样打印。
6、合并--分割
SequenceInputStream(en) en为枚举值1、 SequenceInputStream 是合并流,参数接收一个枚举值2、那么集合中,谁有枚举呢: Vector把流都装入到Vector 形成一个结合3、 SequenceInputStream 接收枚举, 形成合并流。4、 创建一个输入流,并关联文件。
-------------------------------------------------------
【1】
常用方法:
1、创建
常用方法:
1、创建
boolean createNewFile(); 在指定位置常见文件,
如果该文件已经存在,则不创建,返回false,同输出流不一样,输出流建立文件,如果存在,则直接覆盖。
boolean mkdir():创建文件夹(只能是一级目录)boolean mkdirs():创建多级文件夹(D:\\e\\aa\\ee\\dd)
2、删除
boolean delete(); 指定删除void deleteonExit(); 退出时,删除
3、判断
exists() 判断文件或目录【是否存在】。isDirectory() 是否是目录isFile() 是否是文件isHidden() 是否是隐藏文件 (Java是不能使用隐藏文件的)isAbsolute() 是否是绝对路径(E:\\2\\213\2.txt)
4、查找
String getName(); 获取名称getPath() :获取路径getParent(): 获取路径 没有明确指定负目录,返回的是空getAbsolutePath() 获取绝对路径。long lastModifide() :返回最后修改的时间。[last,modifai]long length() : 文件大小。
---------
【重点的部分】
listRoots():列出 系统的盘符。
String list() :列出该盘符下所有的文件夹、文件 保过隐藏部分。
list(FilenameFilter filter): 文件过滤,选出指定文件
File listFiles() :比list()更常用,因为被封装为对象,所以可以获取其名字和长度
-----------------------------------
endsWith(".java") 筛选
renameTo(File dest)
分隔符:File.separator 可以跨平台使用。
因为E:\\ 跨平台性不强
【2】
递归 概念
函数自身调用自身。
这种表现形式,或者说编程手法,称为【递归。【函数自身调用自身。】】
递归注意:
1、限定条件。
2、要注意递归的次数,尽量避免内存溢出。
递归中不要建立集合,因为会自己调用自己会不断创建集合。
【重点的部分】
listRoots():列出 系统的盘符。
String list() :列出该盘符下所有的文件夹、文件 保过隐藏部分。
list(FilenameFilter filter): 文件过滤,选出指定文件
File listFiles() :比list()更常用,因为被封装为对象,所以可以获取其名字和长度
-----------------------------------
endsWith(".java") 筛选
renameTo(File dest)
分隔符:File.separator 可以跨平台使用。
因为E:\\ 跨平台性不强
【2】
递归 概念
函数自身调用自身。
这种表现形式,或者说编程手法,称为【递归。【函数自身调用自身。】】
递归注意:
1、限定条件。
2、要注意递归的次数,尽量避免内存溢出。
递归中不要建立集合,因为会自己调用自己会不断创建集合。
class $3FileDemo {
public static void main(String[] args) {
File dir = new File("E:\\yunyao\\edjava\\");
//showDir(dir);
//toBin(6);
int sum = getSum(8000);
sop(sum);
}
//递归运算示例2:
public static int getSum(int n){
//计算1234一次相加的和
if(n == 1){
return 1;
}
return n+getSum(n-1);
}
//递归运算示例:
public static void toBin(int num){
if(num>0){
toBin(num /2 );
//num = num /2 ;
sop(num%2);
}
}
public static void showDir(File dir){
sop("-----------------------------------");
sop(dir);
sop("--------");
File [] files = dir.listFiles();
for(int i = 0; i<files.length; i++){
if(files[i].isDirectory())
showDir(files[i]);//【再次调用本功能】函数自身调用自身。
else
sop(files[i]+"::"+files[i].length());
}
}
public static void sop(Object obj){
System.out.println(obj);
}
}
//最简单的递归: a 调用b b调用c c打印完后,打印b 然后打印a
// 有这么一个规律:先进后出。(栈的规律也)
class Test{
void showA(){
showB();
sop(A);
}
void showB(){
showC();
sop(B);
}
void showC(){
sop(C);
}
}
【3】
Properties
Properties 是 hashtable 的子类
也就是说它具备 map 集合的特点,而且他里面
存储的【键值对】 都是字符串
是集合中的 和 IO 技术相结合的容器
该对象的特点: 可以用于键值对象的配置文件
是集合中的 和 IO 技术相结合的容器
该对象的特点: 可以用于键值对象的配置文件
(因为配置文件都是存放与电脑,和集合是在内存中。Properties 诞生)
需求。 在指定目录下编写一个配置文件,然后把该文件中传入到Propertise中。
class $8Properties{
public static void main(String[] args) throws IOException{
File f = new File("E:\\bbc.txt");
method_1(f);
method_2(f);//
method_3(f);//
}
//修改某一个数值
public static void method_3(File file)throws IOException{
Properties prop = new Properties();
FileInputStream fis = new FileInputStream(file);
prop.load(fis);
//当需要修改值时,发现setProperty方法只能修改集合中的值,而文件
// 中并没有修改。查看API 发现store()方法和 load 方法对应:
prop.setProperty("laopo","9");
FileOutputStream fos = new FileOutputStream(file);//同样一个流
prop.store(fos,"update");//同样传入流,后面是注释标题:
prop.list(System.out);//列出Properties 建议用该方法。
fis.close();
fos.close();
}
//[method_1 终极进化模式。]
public static void method_2(File file)throws IOException{
Properties prop = new Properties();
FileInputStream fis = new FileInputStream(file);
prop.load(fis);//将集合中数据成对加载Properties 集合中。
//System.out.println(prop);
prop.list(System.out);//列出Properties 建议用该方法。
}
public static void method_1(File file)throws IOException{
BufferedReader bufr = new BufferedReader(new FileReader(file));
String line = null;
Properties prop = new Properties();
int index=0;
while((line=bufr.readLine())!=null){
if(line.contains("=")){ //只对键值对进行分割
String [] str = line.split("=");
prop.setProperty(str[0],str[1]);
}
}
//查看是否成功将数据插入到Properties
Set<String> set =prop.stringPropertyNames();
for(String s : set ){
System.out.println(s+"::"+prop.getProperty(s));
}
}
}
练习案例:
需求:
用于记录应用程序运行次数。
如果使用次数已到,那么给出注册提示。
通常会想到:计数器
但是该计数器定义在程序中,随着程序的运行而存在于内中,并进行自增
随着应用程序的退出,该计数器也会在内存中消失。
下一次在启动该程序,又会重新开始从0计数。
这样就达不到要求。
可以 创建一个 Properties 集合,设定一个计数器键值对。
打开某一个应用程序时,建立一个相对应的计数器集合。初始值为1
再次打开判断是否有该程序的计数器,没有,新建,有,值自增。
当这个值达到某个数值时,提示次数已满。
1、接收文本目录,创建一个BufferedReader 关联文件
2、创建Pro 集合,根据文件名写入键值对。
3、主函数可以用一个循环,运行一次,调用一次计数。
4、输出次数。
public class IO3 {
public static void main(String[] args) throws IOException{
Properties prop = new Properties();//1、创建集合
File file = new File("E:\\cout.ini");//2、把文件封装为对象
if(!file.exists()){ //3、判断文件是否存在
file.createNewFile(); //3-1、如果没有该文件则创建一个。
}
FileInputStream fis = new FileInputStream(file); //4、建立读取流并关联文件
prop.load(fis); //5、载入。键值对数据。
int count = 0;
String value = prop.getProperty("Sum"); //6/获取 key 对应的值 value
System.out.println("模拟启动");
if(value!=null){ // 7、判断有没有该 key
count = Integer.parseInt(value); //7-1、如果有则把 value 值转换为int
if(count>=5){
System.out.println("软件使用次数到期。交钱吧。");
return ;
}
}
count++; // 8、自增一次。
prop.setProperty("Sum",count+""); // 9、 更新数据/一定要通过 count+"" 进行转换
FileOutputStream fos = new FileOutputStream(file); //10、建立输入流并关联文件
prop.store(fos,"update");//11、更新到硬盘文件
fis.close();//12、管理两个缓冲区。
fos.close();
}
}
【4】
打印流 : 可以直接操作输入流和文件。
PrintStreamPrintWriter
该流提供了打印方法,可以将各种数据类型的数据都原样打印。
字节打印流
PrintStream
字节打印流
PrintStream
构造函数可以接收的参数类型:1、file对象2、字符串路径3、字节输出流 OutputStream
字符打印流
PrintWriter
PrintWriter
构造函数可以接收的参数类型:1、file对象2、字符串路径3、字节输出流 OutputStream4、字符输出流 Writer
【5】 合并--分割
对多个流进行合并
SequenceInputStream(en) en为枚举值
对多个流进行合并
SequenceInputStream(en) en为枚举值
1、 SequenceInputStream 是合并流,参数接收一个枚举值2、那么集合中,谁有枚举呢: Vector把流都装入到Vector 形成一个结合3、 SequenceInputStream 接收枚举, 形成合并流。4、 创建一个输入流,并关联文件。
// Vector Enumeration elements SequenceInputStream
实现两个功能:
1、分割
实现两个功能:
1、分割
1、创建读取流并关联文件,声明读写流源,电脑,视频文件: FileInputStream2、创建一个byte 类型数组,大小为需求每个文件的大小3、通过循环方式,new出读写流,并装入数据。4、关闭所有流。
2、合并
老方法:1、因为合并流 SequenceInputStream 的参数必须是枚举,所以需要用到Vector2、创建 Vector 新增被分割的文件。3、枚举 Enumeration en = v.elements4、创建 SequenceInputStream 接收en5、创建读写流 FileOutputStream 并管理文件位置。6、记住 一个字节数组来存储,利用循环。7、关闭所有流
方法2:因为vector 方法效率很低,所以使用 ArrayList 来处理因为 ArrayList 只有迭代没有枚举 所以,使用迭代 建立 枚举内部来来返回 转型。注意,Enumeration 必须重载两个方法,hashCodeElements nextElement剩余步骤一致
// Vector Enumeration SequenceInputStream hasMoreElements nextElement
class $93Test1 {
public static void main(String[] args) throws Exception{
File f = new File("E:\\Test\\mp4");
spiltFile_1(); // 切割
Thread.sleep(2000);
toSequenceInputStream_2(f); // 合并
//toSequenceInputStream_1(f); // 低效率合并--摒弃。
Thread.sleep(3000);//延迟几秒再进行删除
DeleteFile(f); // 删除
}
//【2】 发现分割出问题了,删除错误分割文件
public static void DeleteFile(File dir)throws Exception {
try{
File [] files = dir.listFiles();// 把接收到的路径对象 装入数组中
for(File file : files){ // 递归 判断内部是否还包含文件夹
if(file.isDirectory()){
DeleteFile(file);
}
System.out.println("Dele:"+file.delete());// 删除文件
}
System.out.println("OVER");
//System.out.println("OVER\nDele:"+dir.delete());// 删除文件夹
}
catch (IOException e){
throw new RuntimeException();
}
}
//【1】 分割
public static void spiltFile_1(){
FileInputStream fis =null;
FileOutputStream fos = null;
try{
fis = new FileInputStream("E:\\207.mp4");//读写流 关联文件
int len = 0;
int count = 1;
byte [] by = new byte[1024*1024*10];// 设置 10M
while((len = fis.read(by))!=-1){
fos = new FileOutputStream("E:\\Test\\mp4\\"+(count++)+".part");//创建一个写入流 并关联文件
fos.write(by,0,len);//写入
fos.close();//关闭该流 //循环后,count++ 这个时候关联新的文件。
}
System.out.println("Spilt is Over!");
}
catch (IOException e){
throw new RuntimeException();
}
finally{
try{
if(fis!=null)//切记关闭流
fis.close();
}
catch (IOException e){
throw new RuntimeException();
}
}
}
//【3】 合并
public static void toSequenceInputStream_2(File dir) throws IOException{
SequenceInputStream sis =null;
FileOutputStream fos =null;
BufferedOutputStream bufi=null;
try{
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();// 用该集合取代 低效的 vector
for(int i = 1; i<= 14 ; i++){
al.add(new FileInputStream("E:\\Test\\mp4\\"+i+".part")); // 遍历新增 被分割的文件。
}
final Iterator<FileInputStream> it = al.iterator(); // 因为 ArrayList 没有枚举,只有迭代, 那么我们中转一下。 记住是 final 修饰
Enumeration<FileInputStream> en = new Enumeration<FileInputStream>(){ // 枚举 通过内部类 通过 转换 使枚举 返回 迭代值
public boolean hasMoreElements(){ // 切记覆盖该方法 boolean 类型
return it.hasNext();
}
public FileInputStream nextElement(){ // 切记覆盖该方法 FileInputStrean 类型
return it.next();
}
};
sis = new SequenceInputStream(en);// SequenceInputStream 接收枚举
//fos = new FileOutputStream("E:\\Test\\mp4\\2222.mp4");
bufi =new BufferedOutputStream(new FileOutputStream("E:\\Test\\mp4\\2222.mp4")); // 为了效率
int len = 0;
byte [] by = new byte[1024];// 别忘了字节数组
while((len = sis.read(by))!=-1){ // 读的是数组
bufi.write(by,0,len);//fos.write(by,0,len); // 写入
//bufi.flush();//fos.flush(); // 刷新,其实可以不写。 因为接着就关闭了,自动刷新了。
}
System.out.println("Sequence is Over!");
}
catch (IOException e){
throw new RuntimeException();
}
finally{
try{
if(bufi!=null) //切记关闭流
bufi.close();
}
catch (IOException e)
{
throw new RuntimeException();
}
finally{
try{
if(sis!=null)//切记关闭流
sis.close();
}
catch (IOException e)
{
throw new RuntimeException();
}
}
}
}
// 使用 Vector -- 但是效率不好。
public static void toSequenceInputStream_1(File dir) throws IOException
{
// 1、因为合并流 SequenceInputStream 的参数必须是枚举,所以需要用到Vector
// 2、创建 Vector 新增被分割的文件。
// 3、枚举 Enumeration en = v.elements
// 4、创建 SequenceInputStream 接收en
// 5、创建读写流 FileOutputStream 并管理文件位置。
// 6、记住 一个字节数组来存储,利用循环。
// 7、关闭所有流
File [] files = dir.listFiles();
Vector<FileInputStream> v = new Vector<FileInputStream>();
for(int i = 1 ;i<files.length-1 ; i++){
v.add(new FileInputStream("E:\\Test\\mp4\\"+i+".part"));
}
Enumeration<FileInputStream> en = v.elements();
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream("E:\\Test\\mp4\\008.mp4");
int len = 0;
byte [] by = new byte [1024];
while((len = sis.read(by))!=-1){
fos.write(by,0,len);
fos.flush();
}
System.out.println("Sequence is Over!");
fos.close();
sis.close();
}
}
//end
1、分割,读取文件的时候,
byte [] by = new byte[1024*1024*10]; 设置 10m 来设定 每一个分割文件的大小
2、合并,遍历 新增所有分割文件 到集合中
sis = new SequenceInputStream(en) 接收集合转化的 枚举值 进行文件的合并。
3、删除文件时,注意判断 是否为文件夹 利用 递归 完成。
3、删除文件时,注意判断 是否为文件夹 利用 递归 完成。
---------------------------------------------------------------------------------------------------------------------------------------------
----------
android培训、
java培训、期待与您交流!----------
----------------------------------------------