版权声明:本文为博主原创小文章,转载请联系我,邮箱[email protected] https://blog.csdn.net/qq_39210208/article/details/86574244
File类:
用于将文件和文件夹封装成对象。
1,创建。
boolean createNewFile():如果该文件不存在,会创建,如果已存在,则不创建。不会像输出流一样会覆盖。
boolean mkdir();
boolean mkdirs();
2,删除。
boolean delete();
void deleteOnExit();
3,获取:
String getAbsolutePath();
String getPath();
String getParent();
String getName();
long length();
long lastModified();
4,判断:
boolean exists();
boolean isFile();
boolean isDirectory();
1、需求:对指定目录进行所有内容的列出(包含子目录中的内容)也可以理解为 深度遍历。
public class FileTest {
public static void main(String[] args) {
File dir = new File("e:\\demodir");
listAll(dir,0);
}
public static void listAll(File dir,int level) {
System.out.println(getSpace(level)+dir.getName());
//获取指定目录下当前的所有文件夹或者文件对象
level++;
File[] files = dir.listFiles();
for(int x=0; x<files.length; x++){
if(files[x].isDirectory()){
listAll(files[x],level);
}
else
System.out.println(getSpace(level)+files[x].getName());
}
}
private static String getSpace(int level) {
StringBuilder sb = new StringBuilder();
sb.append("|--");
for(int x=0; x<level; x++){
sb.insert(0,"| ");
}
return sb.toString();
}
}
2、删除一个带内容的目录。
原理:必须从最里面往外删,需要进行深度遍历。
public class RemoveDirTest {
public static void main(String[] args) {
File dir = new File("e:\\demodir");
removeDir(dir);
}
public static void removeDir(File dir) {
File[] files = dir.listFiles();
for(File file : files){
if(file.isDirectory()){
removeDir(file);
}else{
System.out.println(file+":"+file.delete());
}
}
System.out.println(dir+":"+dir.delete());
}
}
Properties
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;
public class PropertiesDemo {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
/*
* Map
* |--Hashtable
* |--Properties:
*
* Properties集合:
* 特点:
* 1,该集合中的键和值都是字符串类型。
* 2,集合中的数据可以保存到流中,或者从流获取。
*
* 通常该集合用于操作以键值对形式存在的配置文件。
*/
// methodDemo_4();
// myLoad();
test();
}
//对已有的配置文件中的信息进行修改。
/*
* 读取这个文件。
* 并将这个文件中的键值数据存储到集合中。
* 在通过集合对数据进行修改。
* 在通过流将修改后的数据存储到文件中。
*/
public static void test() throws IOException{
//读取这个文件。
File file = new File("info.txt");
if(!file.exists()){
file.createNewFile();
}
FileReader fr = new FileReader(file);
//创建集合存储配置信息。
Properties prop = new Properties();
//将流中信息存储到集合中。
prop.load(fr);
prop.setProperty("wangwu", "16");
FileWriter fw = new FileWriter(file);
prop.store(fw,"");
fw.close();
fr.close();
}
//模拟一下load方法。
public static void myLoad() throws IOException{
Properties prop = new Properties();
BufferedReader bufr = new BufferedReader(new FileReader("info.txt"));
String line = null;
while((line=bufr.readLine())!=null){
if(line.startsWith("#"))
continue;
String[] arr = line.split("=");
// System.out.println(arr[0]+"::"+arr[1]);
prop.setProperty(arr[0], arr[1]);
}
prop.list(System.out);
bufr.close();
}
public static void methodDemo_4() throws IOException {
Properties prop = new Properties();
//集合中的数据来自于一个文件。
//注意;必须要保证该文件中的数据是键值对。
//需要使用到读取流。
FileInputStream fis = new FileInputStream("info.txt");
//使用load方法。
prop.load(fis);
prop.list(System.out);
}
public static void methodDemo_3() throws IOException {
Properties prop = new Properties();
//存储元素。
prop.setProperty("zhangsan","30");
prop.setProperty("lisi","31");
prop.setProperty("wangwu","36");
prop.setProperty("zhaoliu","20");
//想要将这些集合中的字符串键值信息持久化存储到文件中。
//需要关联输出流。
FileOutputStream fos = new FileOutputStream("info.txt");
//将集合中数据存储到文件中,使用store方法。
prop.store(fos, "info");
fos.close();
}
/**
* 演示Properties集合和流对象相结合的功能。
*/
public static void methodDemo_2(){
Properties prop = new Properties();
//存储元素。
// prop.setProperty("zhangsan","30");
// prop.setProperty("lisi","31");
// prop.setProperty("wangwu","36");
// prop.setProperty("zhaoliu","20");
prop = System.getProperties();
prop.list(System.out);
}
/*
* Properties集合的存和取。
*/
public static void propertiesDemo(){
//创建一个Properties集合。
Properties prop = new Properties();
//存储元素。
prop.setProperty("zhangsan","30");
prop.setProperty("lisi","31");
prop.setProperty("wangwu","36");
prop.setProperty("zhaoliu","20");
//修改元素。
prop.setProperty("wangwu","26");
//取出所有元素。
Set<String> names = prop.stringPropertyNames();
for(String name : names){
String value = prop.getProperty(name);
System.out.println(name+":"+value);
}
}
}
/*
* 定义功能,获取一个应用程序运行的次数,如果超过5次,给出使用次数已到请注册的提示。并不要在运行程序。
*
* 思路:
* 1,应该有计数器。
* 每次程序启动都需要计数一次,并且是在原有的次数上进行计数。
*
* 2,计数器就是一个变量。 突然冒出一想法,程序启动时候进行计数,计数器必须存在于内存并进行运算。
* 可是程序一结束,计数器消失了。那么再次启动该程序,计数器又重新被初始化了。
* 而我们需要多次启动同一个应用程序,使用的是同一个计数器。
* 这就需要计数器的生命周期变长,从内存存储到硬盘文件中。
*
* 3,如何使用这个计数器呢?
* 首先,程序启动时,应该先读取这个用于记录计数器信息的配置文件。
* 获取上一次计数器次数。 并进行试用次数的判断。
* 其次,对该次数进行自增,并自增后的次数重新存储到配置文件中。
*
* 4,文件中的信息该如何进行存储并体现。
* 直接存储次数值可以,但是不明确该数据的含义。 所以起名字就变得很重要。
* 这就有了名字和值的对应,所以可以使用键值对。
* 可是映射关系map集合搞定,又需要读取硬盘上的数据,所以map+io = Properties.
*/
.
.
public class PropertiesTest {
/**
* @param args
* @throws IOException
* @throws Exception
*/
public static void main(String[] args) throws IOException {
getAppCount();
}
public static void getAppCount() throws IOException{
//将配置文件封装成File对象。
File confile = new File("count.properties");
if(!confile.exists()){
confile.createNewFile();
}
FileInputStream fis = new FileInputStream(confile);
Properties prop = new Properties();
prop.load(fis);
//从集合中通过键获取次数。
String value = prop.getProperty("time");
//定义计数器。记录获取到的次数。
int count =0;
if(value!=null){
count = Integer.parseInt(value);
if(count>=5){
// System.out.println("使用次数已到,请注册,给钱!");
// return;
throw new RuntimeException("使用次数已到,请注册,给钱!");
}
}
count++;
//将改变后的次数重新存储到集合中。
prop.setProperty("time", count+"");
FileOutputStream fos = new FileOutputStream(confile);
prop.store(fos, "");
fos.close();
fis.close();
}
}
/*
* 获取指定目录下,指定扩展名的文件(包含子目录中的)
* 这些文件的绝对路径写入到一个文本文件中。
* 简单说,就是建立一个指定扩展名的文件的列表。
*
* 思路:
* 1,必须进行深度遍历。
* 2,要在遍历的过程中进行过滤。将符合条件的内容都存储到容器中。
* 3,对容器中的内容进行遍历并将绝对路径写入到文件中。
*/
public class Test {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
File dir = new File("e:\\java0331");
FilenameFilter filter = new FilenameFilter(){
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".java");
}
};
List<File> list = new ArrayList<File>();
getFiles(dir,filter,list);
File destFile = new File(dir,"javalist.txt");
write2File(list,destFile);
}
/**
* 对指定目录中的内容进行深度遍历,并按照指定过滤器,进行过滤,
* 将过滤后的内容存储到指定容器List中。
* @param dir
* @param filter
* @param list
*/
public static void getFiles(File dir,FilenameFilter filter,List<File> list){
File[] files = dir.listFiles();
for(File file : files){
if(file.isDirectory()){
//递归啦!
getFiles(file,filter,list);
}else{
//对遍历到的文件进行过滤器的过滤。将符合条件File对象,存储到List集合中。
if(filter.accept(dir, file.getName())){
list.add(file);
}
}
}
}
public static void write2File(List<File> list,File destFile)throws IOException{
BufferedWriter bufw = null;
try {
bufw = new BufferedWriter(new FileWriter(destFile));
for(File file : list){
bufw.write(file.getAbsolutePath());
bufw.newLine();
bufw.flush();
}
} /*catch(IOException e){
throw new RuntimeException("写入失败");
}*/finally{
if(bufw!=null)
try {
bufw.close();
} catch (IOException e) {
throw new RuntimeException("关闭失败");
}
}
}
}
PrintStream
/* 1,提供了打印方法可以对多种数据类型值进行打印。并保持数据的表示形式。
* 2,它不抛IOException.
*
* 构造函数,接收三种类型的值:
* 1,字符串路径。
* 2,File对象。
* 3,字节输出流。
*/
public class PrintStreamDemo {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
PrintStream out = new PrintStream("print.txt");
// int by = read();
// write(by);
// out.write(610);//只写最低8位,
// out.print(97);//将97先变成字符保持原样将数据打印到目的地。
out.close();
}
}
/*
* PrintWriter:字符打印流。
* 构造函数参数:
* 1,字符串路径。
* 2,File对象。
* 3,字节输出流。
* 4,字符输出流。
*/
public class PrintWriterDemo {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new FileWriter("out.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();
}
}
总结:
IO中的其他功能流对象:
1,打印流:
PrintStream:字节打印流。
特点:
1,构造函数接收File对象,字符串路径,字节输出流。意味着打印目的可以有很多。
2,该对象具备特有的方法 打印方法 print println,可以打印任何类型的数据。
3,特有的print方法可以保持任意类型数据表现形式的原样性,将数据输出到目的地。
对于OutputStream父类中的write,是将数据的最低字节写出去。
PrintWriter:字符打印流。
特点:
1,当操作的数据是字符时,可以选择PrintWriter,比PrintStream要方便。
2,它的构造函数可以接收 File对象,字符串路径,字节输出流,字符输出流。
3,构造函数中,如果参数是输出流,那么可以通过指定另一个参数true完成自动刷新,该true对println方法有效。
什么时候用?
当需要保证数据表现的原样性时,就可以使用打印流的打印方法来完成,这样更为方便。
保证原样性的原理:其实就是将数据变成字符串,在进行写入操作。
SequenceInputStream
public static void main(String[] args) throws IOException {
/*
* 需求:将1.txt 2.txt 3.txt文件中的数据合并到一个文件中。
*/
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
for(int x=1; x<=3; x++){
al.add(new FileInputStream(x+".txt"));
}
Enumeration<FileInputStream> en = Collections.enumeration(al);
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream("1234.txt");
byte[] buf = new byte[1024];
int len = 0;
while((len=sis.read(buf))!=-1){
fos.write(buf,0,len);
}
fos.close();
sis.close();
}
SequenceInputStream:
特点:
1,将多个字节读取流和并成一个读取流,将多个源合并成一个源,操作起来方便。
2,需要的枚举接口可以通过Collections.enumeration(collection);
ObjectStream
public class ObjectStreamDemo {
/**
* @param args
* @throws IOException
* @throws ClassNotFoundException
*/
public static void main(String[] args) throws IOException, ClassNotFoundException {
// writeObj();
readObj();
}
public static void readObj() throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.object"));
//对象的反序列化。
Person p = (Person)ois.readObject();
System.out.println(p.getName()+":"+p.getAge());
ois.close();
}
public static void writeObj() throws IOException, IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.object"));
//对象序列化。 被序列化的对象必须实现Serializable接口。
oos.writeObject(new Person("小强",30));
oos.close();
}
}
ObjectInputStream 和 ObjectOutputStream
对象的序列化和反序列化。
writeObject readObject
Serializable标记接口
关键字:transient
RandomAccessFile
public class RandomAccessFileDemo {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
/*
* RandomAccessFile
* 一看这个类名字,纠结。不是io体系中的子类。
*
* 特点:
* 1,该对象即能读,又能写。
* 2,该对象内部维护了一个byte数组,并通过指针可以操作数组中的元素,
* 3,可以通过getFilePointer方法获取指针的位置,和通过seek方法设置指针的位置。
* 4,其实该对象就是将字节输入流和输出流进行了封装。
* 5,该对象的源或者目的只能是文件。通过构造函数就可以看出。
*/
// writeFile();
// readFile();
randomWrite();
}
public static void randomWrite() throws IOException{
RandomAccessFile raf = new RandomAccessFile("ranacc.txt", "rw");
//往指定位置写入数据。
raf.seek(3*8);
raf.write("哈哈".getBytes());
raf.writeInt(108);
raf.close();
}
public static void readFile() throws IOException {
RandomAccessFile raf = new RandomAccessFile("ranacc.txt", "r");
//通过seek设置指针的位置。
raf.seek(1*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);
System.out.println("pos:"+raf.getFilePointer());
raf.close();
}
//使用RandomAccessFile对象写入一些人员信息,比如姓名和年龄。
public static void writeFile() throws IOException{
/*
* 如果文件不存在,则创建,如果文件存在,不创建
*/
RandomAccessFile raf = new RandomAccessFile("ranacc.txt","rw");
raf.write("张三".getBytes());
raf.writeInt(97);
raf.write("小强".getBytes());
raf.writeInt(99);
raf.close();
}
}
RandomAccessFile:
特点:
1,即可读取,又可以写入。
2,内部维护了一个大型的byte数组,通过对数组的操作完成读取和写入。
3,通过getFilePointer方法获取指针的位置,还可以通过seek方法设置指针的位置。
4,该对象的内容应该封装了字节输入流和字节输出流。
5,该对象只能操作文件。
通过seek方法操作指针,可以从这个数组中的任意位置上进行读和写
可以完成对数据的修改。
但是要注意:数据必须有规律。
PipedStream
public class PipedStream {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
PipedInputStream input = new PipedInputStream();
PipedOutputStream output = new PipedOutputStream();
input.connect(output);
new Thread(new Input(input)).start();
new Thread(new Output(output)).start();
}
}
class Input implements Runnable{
private PipedInputStream in;
Input(PipedInputStream in){
this.in = in;
}
public void run(){
try {
byte[] buf = new byte[1024];
int len = in.read(buf);
String s = new String(buf,0,len);
System.out.println("s="+s);
in.close();
} catch (Exception e) {
// TODO: handle exception
}
}
}
class Output implements Runnable{
private PipedOutputStream out;
Output(PipedOutputStream out){
this.out = out;
}
public void run(){
try {
Thread.sleep(5000);
out.write("hi,管道来了!".getBytes());
} catch (Exception e) {
// TODO: handle exception
}
}
}
管道流:需要和多线程技术相结合的流对象。
PipedOutputStream
PipedInputStream
DataSteam
public class DataSteamDemo {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// writeData();
readData();
}
public static void readData() throws IOException {
DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
String str = dis.readUTF();
System.out.println(str);
}
public static void writeData() throws IOException {
DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
dos.writeUTF("你好");
dos.close();
}
}
用操作基本数据类型值的对象。
DataInputStream
DataOutputStream
ByteArrayStream
public class ByteArrayStreamDemo {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) {
ByteArrayInputStream bis = new ByteArrayInputStream("abcedf".getBytes());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int ch = 0;
while((ch=bis.read())!=-1){
bos.write(ch);
}
System.out.println(bos.toString());
}
}
设备是内存的流对象。
ByteArrayInputStream ByteArrayOutputStream
CharArrayReader CharArrayWriter
.
.
.
.
IO流体系:
字符流:
Reader
|--BufferedReader:
|--LineNumberReader
|--CharArrayReader
|--StringReader
|--InputStreamReaer
|--FileReader
Writer
|--BufferedWriter
|--CharArrayWriter
|--StringWriter
|--OutputStreamWriter
|--FileWriter
|--PrintWriter
字节流:
InputStream
|--FileInputStream:
|--FilterInputStream
|--BufferedInputStream
|--DataInputStream
|--ByteArrayInputStream
|--ObjectInputStream
|--SequenceInputStream
|--PipedInputStream
OutputStream
|--FileOutputStream
|--FilterOutputStream
|--BufferedOutputStream
|--DataOutputStream
|--ByteArrayOutputStream
|--ObjectOutputStream
|--PipedOutputStream
|--PrintStream
RandomAccessFile: