19.Java高级视频_IO输入与输出(第二十天)

一   File概述

1、引入File类的概念

因为IO流只是用于操作文件中的内容而不能操作文件夹,因此接下来讲解IO包中另一个重要的类 —File类。

文件中会包含很多的属性和行为信息(大小、时间、只读、隐藏还有里面的内容,各种各样)。

IO流操作的只是数据,但数据最明显的体现形式就是文件。

想要操作被数据封装成文件的信息,必须用File类,它就补充了IO流这方面的不足。

2、关于File类的几点认识

用来将文件或文件夹封装成对象

方便对文件与文件夹进行操作

File对象可以作为参数传递给流的构造函数

了解File类中的常用方法

可以通过API文档来具体了解File类,其中要留意File类的separator属性:

static String separator:与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。

示例代码:

import java.io.*;

public class Demo {
	public static void main(String args[]) throws IOException {
		consMethod();
	}

	// 创建File对象
	public static void consMethod() {
		// 将a.txt封装成 file 对象,可以将已有的和未出现的文件或者文件夹封装成对象。
		File f1 = new File("c:\\java\\demo.txt");
		File f2 = new File("c:\\java", "demo.txt");// 和上面相等
		File d = new File("c:\\java");
		File f3 = new File(d, "demo.txt");// 这样也可以
		File f4 = new File("c:" + File.separator + "java" + File.separator+ "demo.txt");
		sop("f1:" + f1);
		sop("f2:" + f2);
		sop("f3:" + f3);
		sop("f4:" + f4);
	}

	public static void sop(Object obj) {
		System.out.println(obj.toString());
	}
}

二   File对象功能 — 创建和删除

File类既然操作的是文件和文件夹,当然也有增删改查,先来了解它的创建和删除。   

1、创建方法

【掌握】boolean createNewFile()
当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件。

【掌握】boolean mkdir()
创建此抽象路径名指定的目录。

【了解】static File createTempFile(String prefix, String suffix)
在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。

【了解】static File createTempFile(String prefix, String suffix, File directory)
在指定目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。

2、删除方法

【掌握】boolean delete()
删除此抽象路径名表示的文件或目录。

【掌握】void deleteOnExit()
在虚拟机终止时,请求删除此抽象路径名表示的文件或目录。 

注意:因为操作过程中如果发生异常的话,放finally可能删不掉

      (类似于windows系统中无法删除使用中的文件一样),这时就需要用到deleteOnExit()。

示例代码:

import java.io.*;

public class Demo {
	public static void main(String args[]) throws IOException {
		method_1();
	}

	// 创建File对象
	public static void method_1() throws IOException {
		File f = new File("newFile.txt");
		File m = new File("folder");
		sop("mkdir:"+m.mkdir()); //已经有就false,没有就true
		sop("create:" + f.createNewFile()); //create:true
		f.deleteOnExit();
		sop("delete:" + f.delete());//delete:true
	}

	public static void sop(Object obj) {
		System.out.println(obj.toString());
	}
}

三   File对象功能-判断

1、与判断相关的方法

boolean canExecute()   测试应用程序是否可以执行此抽象路径名表示的文件。
boolean canRead() 测试应用程序是否可以读取此抽象路径名表示的文件。
boolean canWrite() 测试应用程序是否可以修改此抽象路径名表示的文件。
int compareTo(File pathname)  按字母顺序比较两个抽象路径名。
boolean exists()   测试此抽象路径名表示的文件或目录是否存在。
boolean isAbsolute()  测试此抽象路径名是否为绝对路径名。 //注意isAbsolute()即使文件不存在也能判断
boolean isDirectory() 测试此抽象路径名表示的文件是否是一个目录。

boolean isFile() 测试此抽象路径名表示的文件是否是一个标准文件。

boolean isHidden()  测试此抽象路径名指定的文件是否是一个隐藏文件。

示例代码:

import java.io.*;

//我C盘java文件夹下有ArrayToolDemo.java"这个文件
public class Demo {
	public static void main(String args[]) throws IOException {
		// method_AbsoluteFile();
		// method_File();
		method_Folder();
	}

	public static void method_AbsoluteFile() {
		File f = new File("c:\\java\\ArrayToolDemo.java");
		sop("canExecute : " + f.canExecute());// true
		sop("canRead : " + f.canRead());// true
		sop("canWrite : " + f.canWrite());// true
		sop("isAbsolute : " + f.isAbsolute());// true
		sop("isDirectory : " + f.isDirectory()); // false
		sop("isFile : " + f.isFile());// true
		sop("isHidden : " + f.isHidden()); // false
	}

	public static void method_File() {
		File f = new File("ArrayToolDemo.java");
		sop("canExecute : " + f.canExecute()); // true
		sop("canRead : " + f.canRead()); // true
		sop("canWrite : " + f.canWrite());// true
		sop("isAbsolute : " + f.isAbsolute()); // false
		sop("isDirectory : " + f.isDirectory()); // false
		sop("isFile : " + f.isFile());// true
		sop("isHidden : " + f.isHidden()); // false
	}

	public static void method_Folder() {
		File f = new File("c:\\java");
		sop("canExecute : " + f.canExecute()); // true
		sop("canRead : " + f.canRead()); // true
		sop("canWrite : " + f.canWrite());// true
		sop("isAbsolute : " + f.isAbsolute()); // true
		sop("isDirectory : " + f.isDirectory()); // true
		sop("isFile : " + f.isFile());// false
		sop("isHidden : " + f.isHidden()); // false
	}

	public static void sop(Object obj) {
		System.out.println(obj);
	}
}

2、要注意的问题

 
import java.io.*;

public class Demo {
	public static void main(String args[]) throws IOException {
		File f1 = new File("c:\\java\\ArrayToolDemo1.java");
		f1.mkdir();// 创建了一个叫“ArrayToolDemo1.java”的文件夹
		// mkdir()只能创建一级目录,不能创建多级目录,要用mkdirs()
		sop(f1.exists());
		sop(new File("c:\\java\\java\\java\\java\\java\\java\\java").mkdirs());
		File f2 = new File("file.txt");
		sop(f2.isDirectory()); //根本不存在,flase,没有意义
		sop(f2.isFile()); <span></span>//根本不存在,flase,没有意义
	}

	public static void sop(Object obj) {
		System.out.println(obj);
	}
}

注意上面的程序,要注意:

  • new File()后,用createNewFile()创建文件,用mkdir()创建一级目录,mkdirs()创建多级目录;

  • isDirectory()和isFile()判断File对象类型是目录还是文件之前,应该先用exists()判断对象是否存在;

  • 像"Demo.java"和"file.txt"这样有后缀的,一样有可能是文件夹;

  • 尽量不要访问硬盘中被隐藏的文件,java读不了。

四   File对象功能-获取


String getName()
String getPath()
String getParent()    此抽象路径名指定父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null
String getAbsolutPath
String getAbsolutFile() 绝对路径对象      //
这个跟上面那个区别是封装成了对象
long lastModified()
long length() 返回由此抽象路径名表示的文件的长度。 
boolean renameTo(File dest) 重新命名此抽象路径名表示的文件。 
演示 getPath和getAbsolutPath,一样的,因为路径本身是绝对的。
如果相对路径,那么才会不一样。
第6分钟左右,
//该方法返回……
lastModified应用:记录被修改的时间,对比是否上一次被修改的,
第10分钟多听几次

五   File对象功能-文件列表

要获取File对象的文件列表,首先要了解对象中文件和文件夹的情况,这时候需要 list()和listRoots() 方法:

String[] list() 返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。//还列出包含隐藏文件

static File[] listRoots()  列出可用的文件系统根。(注意是静态方法)

示例代码:

import java.io.*;
public class Demo {
 public static void main(String args[]) throws IOException {
  listMethod();
  sop("--------------");
  listRootsMethod();
 }
 public static void listMethod() throws IOException {
  File files = new File("c:\\java");
  String[] names = files.list();// 调用list方法的file对象,必须是封装了一个目录,该目录还必须存在
  for (String name : names) {
   sop(name);
  }
 }
 public static void listRootsMethod() {
  File[] f = File.listRoots();
  for (File ff : f) {
   sop(ff);
   sop(ff.length());// 其实这里不能直接拿到盘符所谓的长度
  }
 }
 public static void sop(Object obj) {
  System.out.println(obj.toString());
 }
}

String[] list(FilenameFilter filter)

返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录。

练习:把上面这个方法做一下,就要一个目录下所有的.java文件,其他都不要

六   File对象功能-文件列表2

首先,来了解一下list(FilenameFilter filter)方法中的接口FilenameFilter。

FilenameFilter:实现此接口的类实例可用于过滤器文件名。

该接口只有一个方法:boolean accept(File dir, String name) 测试指定文件是否应该包含在某一文件列表中。

第五节练习的答案示例代码:

import java.io.*;
public class Demo {
 public static void main(String args[]) {
  method_2();
 }
 public static void method_1() {
  File dir = new File("c:\\java");
  String[] arr = dir.list();
  for (String name : arr) {
   sop(name);
  }
 }
 public static void method_2() {
  File dir = new File("c:\\java");
  String[] arr = dir.list(new FilenameFilter()// list方法依据accept方法的返回值过滤文件
    {
     public boolean accept(File dir, String name) {
      // return true; 输出目录所有的文件名
      // return false; 不输出任何东西
      return name.endsWith(".java");
     }
    });
  for (String name : arr) {
   sop(name);
  }
 }
 public static void sop(Object obj) {
  System.out.println(obj.toString());
 }
}

Q:下面两个方法,有什么区别呢?

String[] list() 返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。

File[] listFiles() 返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。

A:list()只返回名称,listFiles()返回的是对象。

import java.io.*;
public class Demo {
 public static void main(String args[]) {
  File file = new File("c:\\java");
  File[] files = file.listFiles();
  for(File java_Files:files){
   System.out.println(java_Files.getName()+" : "+java_Files.length());
  }
 }
}

上面的程序,有局限性。能不能拿当前目录,包括子目录的文件呢?

七   列出目录下所有内容-递归

1、引入递归的思想

上面的程序,要拿到目录以及其子目录中的文件,就需要用到“递归”的思想。

想象有这样的功能:

列出指定目录下文件或者文件夹,包含子目录中的内容(也就是列出指定目录下所有内容),

在列出过程中如果出现的还是目录,还可以再次调用本功能,继续遍历直到全部列出为止。

类似于这种函数自身调用自身的编程手法,称作“递归”。

递归要注意:

  • 限制条件
  • 要注意递归次数,避免内存溢出

2、递归的例子

import java.io.*;

public class Demo {
	public static void main(String args[]) {
		System.out.println(getSum(10));
	}

	public static int getSum(int n) {
		if (n == 1)
			return 1;
		return n + getSum(n - 1);
	}
}

上面是简单的加法递归,“1+2+3……+10”=55

注意:如果是getSum(8000),会发生溢出,Exception in thread "main" java.lang.StackOverflowError。

简单来说,因为递归时递归的方法在栈内存中,上一个方法没结束,又产生新方法,

而且只有新方法运算完返回结果,上一个方法才能继续运行。

就这样过多占用内存引发错误,因此要注意递归的次数。

3、列出文件夹中全部文件的程序

import java.io.*;

public class Demo {

	public static void main(String args[]) throws IOException {
		File dir = new File("c:\\java");
		showDir(dir);
	}

	public static void showDir(File dir) throws IOException {
		sop(dir);
		File[] files = dir.listFiles();
		for (int x = 0; x < files.length; x++) {
			if (files[x].isDirectory()) {
				showDir(files[x]);
			} else {
				sop(files[x]);
			}
		}
	}

	public static void toBin(int num) {
		while (num > 0) {
			num = num / 2;
			toBin(num);
		}
	}

	public static void sop(Object obj) {
		System.out.println(obj.toString());
	}
}

八   列出目录下所有内容-带层次

上面的程序代码,列出文件和文件夹后,层次不分明,为观看方便,修改代码如下:

import java.io.*;

public class Demo {
	public static void main(String args[]) throws IOException {
		File dir = new File("c:\\java");
		showDir(dir, 0);
	}

	public static String getLevel(int level) {
		StringBuilder sb = new StringBuilder();
		sb.append("|----"); // 做法2
		for (int x = 0; x < level; x++) {
			// sb.append("|----");做法1
			sb.insert(0, "| ");// 做法2

		}
		return sb.toString();
	}

	public static void showDir(File dir, int level) throws IOException {
		sop(getLevel(level) + dir);
		level++;
		File[] files = dir.listFiles();
		for (int x = 0; x < files.length; x++) {
			if (files[x].isDirectory()) {
				showDir(files[x], level);
			} else {
				sop(getLevel(level) + files[x]);
			}
		}
	}

	public static void sop(Object obj) {
		System.out.println(obj.toString());
	}
}

九   删除带内容的目录

如果我们想删除带内容的目录,首先要知道删除原理:

在window中,删除目录从里面往外删除。

既然是从里往外删除,就需要用到递归。

示例代码:

import java.io.*;

public class Demo {
	public static void main(String args[]) throws IOException {
		File dir = new File("c:\\java");
		removeDir(dir);
	}

	public static void removeDir(File dir) throws IOException {
		File[] files = dir.listFiles();
		for (int x = 0; x < files.length; x++) {
			if (!files[x].isHidden() && files[x].isDirectory()) {
				removeDir(files[x]);
			} else {
				sop(files[x].toString() + "::" + files[x].delete());
			}
		}
		sop(dir + "::dir::" + dir.delete());
	}

	public static void sop(Object obj) {
		System.out.println(obj.toString());
	}
}

注意:像C盘有些隐藏目录,java无法访问不能去删,listFiles()返回的数组为空,一为空就报空指针异常。

十   创建java文件列表

练习:

将一个指定目录下的java文件的绝对路径,存储到一个文本文件中,建立一个java文件列表文件


思路:

  1. 对指定的目录进行递归
  2. 获取递归过程中的java文件路径
  3. 将这些路径存储到集合中
  4. 将集合中的数据写入到一个文件中

示例代码:

import java.io.*;
import java.util.*;

public class Demo {
	public static void main(String args[]) throws IOException {
		File dir = new File("c:\\java");
		List<File> list = new ArrayList<File>();
		fileToList(dir, list);
		File file = new File(dir, "demo.txt");
		writeToFile(list, file.toString());
	}

	public static void fileToList(File dir, List<File> list) throws IOException {
		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 void writeToFile(List<File> list, String javaListFile)
			throws IOException {
		BufferedWriter bufw = null;
		try {
			bufw = new BufferedWriter(new FileWriter(javaListFile));
			for (File f : list) {
				String path = f.getAbsolutePath();
				bufw.write(path);
				bufw.newLine();
				bufw.flush();
			}
		} catch (IOException e) {
			throw e;
		} finally {
			try {
				if (bufw != null) {
					bufw.close();
				}
			} catch (IOException e) {
			}
		}
	}

	public static void sop(Object obj) {
		System.out.println(obj.toString());
	}
}

十一   Properties简述

下面来认识一下Properties类。

API文档:“Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。

毕老师:

Properties是Hashtable的子类,也就是说它具备map集合的特点,而且它里面存储的键值对都是字符串。

Properties是和IO技术相结合的集合容器

Properties特点:可以用于键值对形式的配置文件。在加载数据时候,需要数据有固定格式:键-值

既然Properties用于配置文件,那什么是配置文件?

软件的基本配置信息会存储在文件当中,这样的文件就是配置文件。

例如,把EditPlus的编码风格颜色修改后(关键字 - 红色),程序退出后内存就没有EditPlus的进程了,

但是改动在下次启动时依然有效,也就是改动过程中做了持久化处理。

其实就是把改动的信息保存到了配置文件当中去了。

这种键值对信息一般存在文件,而要操作文件又用到流,所以就有了Properties这个类。

十二   Properties存取

Properties一些方法的截取:

  • String getProperty(String key)    用指定的键在此属性列表中搜索属性。
  • Object setProperty(String key, String value)    调用 Hashtable 的方法 put。
  • void list(PrintStream out)    将属性列表输出到指定的输出流。
  • void list(PrintWriter out)    将属性列表输出到指定的输出流。
  • void load(InputStream inStream)    从输入流中读取属性列表(键和元素对)。
  • void load(Reader reader)    按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。
  • Set<String> stringPropertyNames()    返回此属性列表中的键集,其中该键及其对应值是字符串,如果在主属性列表中未找到同名的键,则还包括默认属性列表中不同的键。 

import java.io.*;
import java.util.*;

public class Demo {
	public static void main(String args[]) throws IOException {
		setAndGet();
	}

	// 设置和获取元素
	public static void setAndGet() {
		Properties prop = new Properties();
		prop.setProperty("zhangsan", "30");
		prop.setProperty("lisi", "39");
		sop(prop.toString());
		String value = prop.getProperty("lisi");
		sop(value);
		prop.setProperty("lisi", "98");
		Set<String> names = prop.stringPropertyNames();
		for (String s : names) {
			sop(s + ":" + prop.getProperty(s));
		}
	}

	public static void sop(Object obj) {
		System.out.println(obj.toString());
	}
}

输出:

{zhangsan=30, lisi=39}

39

zhangsan:30

lisi:98

上面的程序其实只是简单地用到Properties的get、set方法,

跟在Hashtable存些键值对没什么区别,下面就来真的了。

十三   Properties存取配置文件

假如Properties数据已经存在了,而不是我们像上面那样通过写代码的形式存进去的,那又是如何获取呢?

演示:如何将流中的数据存储到集合中(将 info.txt 中的键值对数据存到集合中进行操作)

思路:

  • 用一个流和info.txt文件关联
  • 读取一行数据。将改行数据用"="进行切割。
  • 等号左边作为键,右边作为值,存入到Properties集合中即可
import java.io.*;
import java.util.*;

public class Demo {
	public static void main(String args[]) throws IOException {
		loadDemo();
	}

	public static void loadDemo() throws IOException {
		FileInputStream fis = new FileInputStream("info.txt");
		Properties prop = new Properties();
		prop.load(fis);// 将流中的数据加载进集合
		sop(prop);
		FileOutputStream fos = new FileOutputStream("info.txt");
		prop.store(fos, "haha");// 将此 Properties 表中的属性列表(键和元素对)写入输出流
		prop.list(System.out);
		fos.close();
		fis.close();
	}

	// 设置和获取元素
	public static void method() 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("=");
			prop.setProperty(arr[0], arr[1]);
			sop(prop);
		}
	}

	public static void sop(Object obj) {
		System.out.println(obj.toString());
	}
}

注意:public void load(Reader reader)  throws IOException  JDK1.6才有这个方法

十四   Properties练习

问题:有些软件下载后,会限制使用次数,满一定使用次数后要求注册。这种情况如何实现呢?

思考:记录应用程序运行次数,如果次数已到,那么给出注册提示。我们很容易想到的是:计数器。

       该计数器定义在程序中,随着程序的运行而在内存中存在,并进行自增。

       可是,随着该应用程序的退出,该计数器也会在内存中消失了。

       下一次在启动该程序,又重新开始从0计数,这不是我们想要的。

       我们想要程序即使结束,该计数器的值也存在,下次程序启动在会先加载该计数器的值并加1后再重新存储起来。

       所以,可以通过建立一个配置文件,用于记录该软件的使用次数。该配置文件使用键值对的形式,这样方便阅读数据,并操作数据。

简单来说:键值对数据用到map集合,数据是以文件形式存储要用到IO技术    →   properties

示例代码:

import java.io.*;
import java.util.*;

public 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();
	}
}

上面的程序,将使用次数存在了“count.ini”文件中,那么配置文件具体有什么应用呢?

我们可以在Tomcat服务器的文件夹中找到"catalina.properties"这样的文件,里面就有关于Tomcat的配置信息。

此外,配置文件还可以实现应用程序数据的共享。

配置信息要么是properties,要么是xml。下面是XML形式的配置信息示例:

<persons>

	<person id="001">
		 <name>zhangsan/name>
		 <age>12</age>
	</person>
	
	<person id="002">
		 <name>lisi/name>
		 <age>13</age>
	</person>
	
</persons>

以后还有DOM4J这样方便的工具来操作xml配置信息。

十五   PrintWriter

下面来认识一下打印流,PrintWriter 与 PrintStream,它们提供了打印方法,

可以将各种数据类型的数据都原样打印可以直接操作输入流和文件。

(1) PrintStream字节打印流

PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。能保证数据原样性打印出去。

构造函数可以接受的参数类型:

  • File对象,File

  • 字符串路径,String

  • 字节输出流,OutputStream

(2) PrintWriter字符打印流

非常常用!!!可以将信息逐条打印到客户端。

构造函数可以接受的参数类型(目的):

  • File对象,File
  • 字符串路径,String
  • 字节输出流,OutputStream,包含控制台,即System.out
  • 字符输出流,Writer

PrintWriter(OutputStream out, boolean autoFlush):通过现有的 OutputStream 创建新的 PrintWriter。

autoFlush“自带刷新” - boolean 变量;如果为 true,则 println、printf 或 format 方法将刷新输出缓冲区。

示例代码:

import java.io.*;

public class Demo {
	public static void main(String args[]) throws Exception {
		BufferedReader bufr = new BufferedReader(new InputStreamReader(
				System.in));
		// PrintWriter out = new PrintWriter(System.out,true);
		// 可以直接System.out打印到控制台
		PrintWriter out = new PrintWriter(new FileWriter("demo.txt"), true);
		String line = null;
		while ((line = bufr.readLine()) != null) {
			if ("over".equals(line)) {
				break;
			}
			out.println(line.toUpperCase());
			// out.flush();
		}
		out.close();
		bufr.close();
	}

	public static void sop(Object obj) {
		System.out.println(obj.toString());
	}
}

如果不是"out.print"而是"out.println",

那么由于不带自动刷新,打开文件会发现没有换行。

“记住,凡是能直接操作File类对象的流都是比较重要的。

十六   合并流

接着说一下序列流  SequenceInputStream,它可以对多个流进行合并。

API文档:

“SequenceInputStream 表示其他输入流的逻辑串联。

它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,

接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。”


什么意思?就是多个流对象拼成一个流对象。

之前一个流只能关联一个文件,读到最后-1就结束,但SequenceInputStream可以读到最后一个文件的-1才结束。

多个源对应一个目的,中间一个流作为转换。先将多个源变成一个源(SequenceInputStream),再写入目的。

很丑的示意图:

文件1 \

文件2 ——→  SequenceInputStream → 文件4

文件3 /

示例代码:

import java.io.*;
import java.util.*;

public class Demo {
	public static void main(String args[]) throws IOException {
		Vector<FileInputStream> v = new Vector<FileInputStream>();
		v.add(new FileInputStream("1.txt"));
		v.add(new FileInputStream("2.txt"));
		v.add(new FileInputStream("3.txt"));
		
		Enumeration<FileInputStream> en = v.elements();
		SequenceInputStream sis = new SequenceInputStream(en);
		FileOutputStream fos = new FileOutputStream("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();
	}

	public static void sop(Object obj) {
		System.out.println(obj.toString());
	}
}

使用Vector集合收集多个流,再通过Enumeration迭代集合,将获得元素作为参数传入SequenceInputStream。

1.txt 里面全是1,2.txt 里面全是2,3.txt 里面全是3;

合并后就是“111……2222……3333……”这样一个文件4。

十七   切割文件

能合并就能切割。 

写个例子:一个读取流→三个输出流

import java.io.*;
import java.util.*;

public class Demo {

	public static void main(String args[]) throws Exception {
		splitFile();
		merge();
	}

	public static void splitFile() throws Exception {
		FileInputStream fis = new FileInputStream("Demo.mp3");
		FileOutputStream fos = null;
		byte[] buf = new byte[1024 * 1024];
		int len = 0;
		int count = 1;
		while ((len = fis.read(buf)) != -1) {
			fos = new FileOutputStream("Demo-" + (count++) + ".part");
			fos.write(buf, 0, len);
			fos.close();
		}
		fis.close();
	}

	public static void merge() throws Exception {
		ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
		for (int x = 1; x < 10; x++) {
			al.add(new FileInputStream("Demo-" + x + ".part"));
		}
		final Iterator<FileInputStream> it = al.iterator();
		Enumeration<FileInputStream> en = new Enumeration<FileInputStream>() {
			public boolean hasMoreElements() {
				return it.hasNext();
			}

			public FileInputStream nextElement() {
				return it.next();
			}
		};
		SequenceInputStream sis = new SequenceInputStream(en);
		FileOutputStream fos = new FileOutputStream("Demo_part.mp3");
		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 sop(Object obj) {
		System.out.println(obj.toString());
	}

}
将Demo.mp3文件读取存入数组时,一旦数组满了就立刻存入一个文件,并关闭文件,

下一个数组存入另一文件,直到存完。对于大的数据,不能一次定义大的数组,

可以定义小数组,存入文件,等积累到一个量后,关闭文件。

在使用Python来安装geopandas包时,由于geopandas依赖于几个其他的Python库(如GDAL, Fiona, Pyproj, Shapely等),因此安装过程可能需要一些额外的步骤。以下是一个基本的安装指南,适用于大多数用户: 使用pip安装 确保Python和pip已安装: 首先,确保你的计算机上已安装了Python和pip。pip是Python的包管理工具,用于安装和管理Python包。 安装依赖库: 由于geopandas依赖于GDAL, Fiona, Pyproj, Shapely等库,你可能需要先安装这些库。通常,你可以通过pip直接安装这些库,但有时候可能需要从其他源下载预编译的二进制包(wheel文件),特别是GDAL和Fiona,因为它们可能包含一些系统级的依赖。 bash pip install GDAL Fiona Pyproj Shapely 注意:在某些系统上,直接使用pip安装GDAL和Fiona可能会遇到问题,因为它们需要编译一些C/C++代码。如果遇到问题,你可以考虑使用conda(一个Python包、依赖和环境管理器)来安装这些库,或者从Unofficial Windows Binaries for Python Extension Packages这样的网站下载预编译的wheel文件。 安装geopandas: 在安装了所有依赖库之后,你可以使用pip来安装geopandas。 bash pip install geopandas 使用conda安装 如果你正在使用conda作为你的Python包管理器,那么安装geopandas和它的依赖可能会更简单一些。 创建一个新的conda环境(可选,但推荐): bash conda create -n geoenv python=3.x anaconda conda activate geoenv 其中3.x是你希望使用的Python版本。 安装geopandas: 使用conda-forge频道来安装geopandas,因为它提供了许多地理空间相关的包。 bash conda install -c conda-forge geopandas 这条命令会自动安装geopandas及其所有依赖。 注意事项 如果你在安装过程中遇到任何问题,比如编译错误或依赖问题,请检查你的Python版本和pip/conda的版本是否是最新的,或者尝试在不同的环境中安装。 某些库(如GDAL)可能需要额外的系统级依赖,如地理空间库(如PROJ和GEOS)。这些依赖可能需要单独安装,具体取决于你的操作系统。 如果你在Windows上遇到问题,并且pip安装失败,尝试从Unofficial Windows Binaries for Python Extension Packages网站下载相应的wheel文件,并使用pip进行安装。 脚本示例 虽然你的问题主要是关于如何安装geopandas,但如果你想要一个Python脚本来重命名文件夹下的文件,在原始名字前面加上字符串"geopandas",以下是一个简单的示例: python import os # 指定文件夹路径 folder_path = 'path/to/your/folder' # 遍历文件夹中的文件 for filename in os.listdir(folder_path): # 构造原始文件路径 old_file_path = os.path.join(folder_path, filename) # 构造新文件名 new_filename = 'geopandas_' + filename # 构造新文件路径 new_file_path = os.path.join(folder_path, new_filename) # 重命名文件 os.rename(old_file_path, new_file_path) print(f'Renamed "{filename}" to "{new_filename}"') 请确保将'path/to/your/folder'替换为你想要重命名文件的实际文件夹路径。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值