——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
File类
File类用来将文件或者文件夹封装成对象,方便对文件与文件夹的属性信息进行操作。
File对象可以作为参数传递给流的构造函数。
创建File对象
public static void consMethod()
{
//可以将已有的和未出现的文件或者文件夹封装成对象。
//创建File对象
File f1 = new File("a.txt");
//创建包含父路径的File对象
File f2 = new File("c:\\abc","b.txt");
//把抽象路径封装成File对象
File d = new File("c:\\abc");
//把抽象路径File对象传递给构造函数创建新的File对象
File f3 = new File(d,"c.txt");
//考虑到不同系统的兼容性问题,可以使用File.separator代替目录分隔符
File f4 = new File("c:"+File.separator+"abc"+File.separator+"zzz"+File.separator+"a.txt");
}
File.separator是与系统有关的默认名称分隔符。在 UNIX 系统上,此字段的值为 ‘/’;在 Microsoft Windows 系统上,它为 ‘\’。
File对象的常用方法:
一、获取
import java.io.File;
import java.text.DateFormat;
import java.util.Date;
public class FileMethodDemo{
public static void main(String[] args){
getDemo();
}
public static void getDemo(){
//创建File对象
File file1 = new File("a.txt" );
//创建带路径的File对象
File file2 = new File("d:\\demo\\a.txt" );
//获取File对象的名称
String name = file2.getName();
//获取File对象的绝对路径
String absPath = file2.getAbsolutePath();
//获取File对象的抽象路径(创建对象的封装的路径)
String path2 = file2.getPath();
//获取文件的字节数大小
long len = file2.length();
//获取文件的最后修改时间
long time = file2.lastModified();
//获取文件的父目录(创建对象时封装的父路径)
//如果没有指定父目录,则返回 null
String parent1 = file1.getParent();
String parent2 = file2.getParent();
//用自定义日期格式初始化最后修改文件的时间
Date date = new Date(time);
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG);
String str_time = df.format(date);
}
}
二、创建和删除
import java.io.File;
import java.io.IOException;
public class FileMethodDemo{
public static void main(String[] args) throws IOException {
createAndDeleteDemo();
}
public static void createAndDeleteDemo() throws IOException {
//创建File对象
File file = new File("file.txt" );
//使用File对象创建新文件
//如果文件不存在,则创建,如果文件存在,则不创建
boolean b1 = file.createNewFile();
System.out.println( "b1 = " + b1);
//使用delete方法删除File对象对应的文件或文件夹
//使用delete方法删除文件夹的时候,如果文件夹中有文件,会删除失败
boolean b2 = file.delete();
System.out.println( "b2 = " + b2);
//创建封装了路径的File对象
File dir = new File("abc" );
//创建封装了多级路径的File对象
File dir = new File("abc\\ab\\cc" );
//使用mkdir可以创建文件夹
boolean b3 = dir.mkdir();
System.out.println( "b3 = " + b3);
//使用mkdirs可以创建多级文件夹
boolean b3 = dir.mkdirs();
System.out.println( "b4 = " + b4);
//最里层目录被干掉,dir代表的是最里层的目录
boolean b5 = dir.delete();
}
}
三、判断
import java.io.File;
import java.io.IOException;
public class FileMethodDemo{
public static void main(String[] args) throws IOException {
isDemo();
}
public static void isDemo() throws IOException {
File f = new File("aaa.txt" );
//判断File对象对应的文件或文件夹存不存在
boolean b = f.exists();
System.out.println( "b = " + b);
if(!f.exists()){
f.createNewFile();
}
//最好先判断是否存在
if(f.exists()){
//判断File对象对应的是不是文件
System.out.println(f.isFile());
//判断File对象对应的是不是文件夹
System.out.println(f.isDirectory());
}
f = new File("aa\\bb" );
f.mkdirs();
if(f.exists()){
System.out.println(f.isFile());
System.out.println(f.isDirectory());
}
}
}
四、重命名
import java.io.File;
import java.io.IOException;
public class FileMethodDemo{
public static void main(String[] args) throws IOException {
renameToDemo();
}
public static void renameToDemo() throws IOException {
//f1已存在
File f1 = new File("d:\\code\\day21\\0.mp3" );
//f2不存在
File f2 = new File("d:\\code\\day21\\1.mp3" );
//把f1文件重命名成f2
boolean b = f1.renameTo(f2);
System.out.println( "b = " + b);
}
}
五、系统根目录和容量获取
import java.io.File;
import java.io.IOException;
public class FileMethodDemo{
public static void main(String[] args) throws IOException {
listRootsDemo();
}
public static void listRootsDemo() throws IOException {
//获取系统根目录下的file对象数组
File[] files = File.listRoots();
//打印file对象数组
for(File file : files){
System.out.println(file);
}
//把D盘封装成File对象
File file = new File("d:\\" );
//获取D盘的剩余容量字节数大小
System.out.println( "getFreeSpace:" + file.getFreeSpace());
//获取D盘的全部容量字节数大小
System.out.println( "getTotalSpace:" + file.getTotalSpace());
//获取D盘已使用容量字节数大小
System.out.println( "getUsableSpace:" + file.getUsableSpace());
}
}
六、获取目录下的文件及文件夹
import java.io.File;
import java.io.FilenameFilter;
public class FileListDemo{
public static void main(String[] args){
listDemo();
}
public static void listDemo(){
File file = new File("c:\\" );
//获取目录下所有对象名称,返回字符串数组(包含隐藏文件,目录下没有内容时返回的数组长度为0)
//File对象中封装的必须是目录,否则会发生异常(访问系统级目录也会发生异常)
String[] names = file.list();
//打印名称
for(String name : names){
System.out.println(name);
//使用自定义的规则获取需要的列表
String[] names = dir.list(new FilterByJava());
}
}
//自定义获取目录列表的规则,并实现FilenameFilter接口
class FilterByJava implements FilenameFilter{
//实现接口中的accept方法,定义返回规则
public boolean accept(File dir,String name){
//符合规则返回真,否则返回假
//这里文件名是".java"结尾的返回真
return name.endsWith(".java" );
}
}
七、其他方法
File file = new File("a.txt" );
//判断该文件或文件夹是否隐藏(文件必须存在)
file.isHidden();
Properties对象:
hashtable的子类,即具有Map的特性,可以存储键值对,还可以从流中加载跟输出键值对信息
集合中的键和值都是字符串类型
通常用于操作以键值对形式存在的配置文件
import java.util.*;
public class PropertiesDemo{
public static void main(String[] args){
propertiesDemo();
}
public static void propertiesDemo(){
//创建一个Properties集合
Properties prop = new Properties();
//存储元素
prop.setProperty( "zhangsan","10" );
prop.setProperty( "lisi","20" );
prop.setProperty( "wangwu","30" );
prop.setProperty( "zhaoliu","40" );
//修改元素
prop.setProperty( "wangwu","26" );
//取出所有元素
//获取Properties的键集合
Set<String> names = prop.stringPropertyNames();
for(String name : names){
//通过Properties的键获得值
String value = prop.getProperty(name);
System.out.println(name + ":" + value);
}
}
}
/*
记录应用程序运行次数。
如果使用次数已到,那么给出注册提示,并不要再运行程序
即应该有计数器,并有文件保存计数器信息
*/
import java.io.*;
import java.util.*;
public class PropertiesTest{
public static void main(String[] args) throws IOException{
getAppCount();
}
public static void getAppCount() throws IOException {
//创建Properties对象
Properties prop = new Properties();
//创建记录次数的文件count.ini并与File对象关联起来
File file = new File("count.ini");
//文件不存在则创建
if(!file.exists())
file.createNewFile();
//把文件输入字节流与File对象关联起来
FileInputStream fis = new FileInputStream(file);
//从输入流中读取键值对到Properties对象中
prop.load(fis);
//创建记录次数的变量count
int count = 0;
//从Properties对象中读取记录的次数(此时为字符串)
String value = prop.getProperty("time");
//如果文件中存在该键值
if(value!=null)
{
//把该值转换成Int类型并赋给count
count = Integer.parseInt(value);
//如果超过指定次数则打印提示信息,
if(count>=5)
{
System.out.println("您好,使用次数已到,拿钱!");
return ;
}
}
else{
//让运行次数加1
count++;
//运行该程序
appRun();
}
//在Proterties对象中存储新的次数键值对
prop.setProperty("time",count+"");
//把文件输出字节流与File对象关联起来
FileOutputStream fos = new FileOutputStream(file);
//把Properties对象的键值对写入到输出流中
prop.store(fos,"");
//输出流关闭时会先把数据刷新到文件中
fos.close();
fis.close();
}
public static void appRun(){
System.out.println("软件来了!");
}
}
打印流:
可以直接操作输入流和文件。
打印流为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。
与其他输出流不同,打印流永远不会抛出IOException,它可以捕获自己的异常。
打印流打印的所有字符都使用平台的默认字符编码转换为字节。提供了打印方法可以对多种数据类型值进行打印,并保持数据的表示形式
PrintStrean是写入一串8bit的数据的。
PrintWriter是写入一串16bit的数据的。
PrintStream主要操作byte流,而PrintWriter用来操作字符流。读取文本文件时一般用后者。
字节打印流:
PrintStream
构造函数可以接收的参数类型:
- file对象。File
- 字符串路径。String
- 字节输出流。OutputStream
字符打印流:
PrintWriter
构造函数可以接收的参数类型:
- file对象。File
- 字符串路径。String
- 字节输出流。OutputStream
- 字符输出流,Writer。
/*
键盘写入数据到out.txt文件中
*/
import java.io.*;
class PrintWriterDemo
{
public static void main(String[] args) throws IOException
{
//标准键盘输入
BufferedReader bufr =
new BufferedReader(new InputStreamReader(System.in));
//把打印字符输出流与文件关联起来,构造函数的第二个参数设置true表示自动刷新
PrintWriter out = new PrintWriter(new FileWriter("a.txt"),true);
String line = null;
//循环读取键盘输入的一行数据
while((line=bufr.readLine())!=null)
{
//为over就结束循环
if("over".equals(line))
break;
//否则把输入的数据转成大写
out.println(line.toUpperCase());
//不用刷新因为上面的true设置了自动刷新
//out.flush();
}
out.close();
bufr.close();
}
}
合并流
SequenceInputStream:对多个流进行合并。
/*
需求:将1.txt、2.txt、3、txt文件中的数据合并到一个文件中。
*/
import java.io.*;
import java.util.*;
public class SequenceInputStreamDemo{
public static void main(String[] args) throws Exception {
//创建ArrayList集合用来存储要合并的输入流
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
//把要合并的输入流添加到ArrayList集合中
for(int x = 1; x <= 3; x++){
al.add( new FileInputStream(x + ".txt" ));
}
//获取ArrayList集合的迭代器
final Iterator<FileInputStream> it = al.iterator();
//获取ArrayList集合上的枚举
Enumeration<FileInputStream> en = Collections.enumeration(al);
/*
//Collections工具类的enumeration方法核心代码:
Enumeration<FileInputStream> en = new Enumeration<FileInputStream>(){
public boolean hasMoreElements(){
return it.hasMoreElements();
}
public FileInputStream nextElement(){
return it.next();
}
};*/
//创建合并流并通过集合上的枚举初始化该流
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();
}
}
文件的分割
import java.io.*;
import java.util.*;
public class SplitFileDemo{
private static final int SIZE = 1024*1024;
public static void main(String[] args) throws IOException{
File file = new File("0.mp3" );
splitFile(file);
}
public static void splitFile(File file) throws IOException {
//用输入流关联源文件
FileInputStream fis = new FileInputStream(file);
//定义一个1M的缓冲区
byte[] buf = new byte[SIZE];
//创建输出流
FileOutputStream fos = null;
int len = 0;
int count = 1;
//切割文件时,必须记录住被切割文件的名称,以及切割出来碎片文件的个数,以方便于合并。
//这个信息为了进行描述,使用键值对的方式,用到了properties对象。
Properties prop = new Properties();
//创建保存键值对的文件
File dir = new File("c:\\partFiles" );
if(!dir.exists())
dir.mkdirs();
//将输入流循环写入到缓冲区中,直到数据为空
while((len = fis.read(buf)) != -1){
//每读一次就把缓冲区中的数据写入到一个part文件中
fos = new FileOutputStream(new File(dir,(count++) + ".part"));
fos.write(buf,0,len);
fos.close();
}
//将被切割文件的信息保存到prop集合中
prop.setProperty( "partcount",count + "" );
prop.setProperty( "filename",file.getName());
fos = new FileOutputStream(new File(dir,count + ".properties" ));
//将prop集合中的数据存储到文件中
prop.store(fos, "save file info");
fis.close();
fos.close();
}
}
对象的序列化:
序列化堆内存中的对象
Serializable接口:要序列化对象必须要实现Serializable接口,接口中没有方法,会赋予对象一个UID号(long型的值),只是一个标记接口。
import java.io.*;
class ObjectStreamDemo
{
public static void main(String[] args) throws Exception
{
//writeObj();
readObj();
}
public static void readObj()throws Exception
{
//创建对象输入流对象并关联obj.txt文件
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));
//从该流中读取对象并转换成Person对象
Person p = (Person)ois.readObject();
System.out.println(p);
ois.close();
}
public static void writeObj()throws IOException
{
//创建对象输出流对象并关联obj.txt文件
ObjectOutputStream oos =
new ObjectOutputStream(new FileOutputStream("obj.txt"));
//把Person对象写出到流中
oos.writeObject(new Person("lisi0",399,"kr"));
oos.close();
}
}
静态不能被序列化,因为静态成员在方法区中
加上修饰符transient的成员也无法被序列化
自定义UID:任意修饰符+static final long serialVersionUID = 42L;
管道流:
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("读取前。。没有数据阻塞");
//等待输出流的数据输入,这是阻塞式方法,获取数据会存储到buf中
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:
具备读和写功能,内部封装了数组,通过指针操作
内部封装了输入及输出流,只能操作文件
如果模式为只读r。不会创建文件。会去读取一个已存在文件,如果该文件不存在,则会出现异常。
如果模式rw。操作的文件不存在,会自动创建。如果存则不会覆盖。
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");
//调整对象中指针到第8个二进制位(从0开始),即从第二个字节开始读起。
//raf.seek(8*1);
//跳过指定的字节数
raf.skipBytes(8);
byte[] buf = new byte[4];
//读取数据到buf中,一次读buf.length个字节
raf.read(buf);
String name = new String(buf);
//直接读32位整数,即读4个字节
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);
//写入byte数据
raf.write("周期".getBytes());
//写入4个字节的int数据
raf.writeInt(103);
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();
}
}
DataStream基本数据类型流:
用于操作基本数据类型
import java.io.*;
class DataStreamDemo
{
public static void main(String[] args) throws IOException
{
//writeData();
//readData();
//writeUTFDemo();
//readUTFDemo();
}
public static void readUTFDemo()throws IOException
{
DataInputStream dis = new DataInputStream(new FileInputStream("utfdate.txt"));
//使用UTF的编码方式读取一个字符。
String s = dis.readUTF();
System.out.println(s);
dis.close();
}
public static void writeUTFDemo()throws IOException
{
DataOutputStream dos = new DataOutputStream(new FileOutputStream("utfdate.txt"));
//写入一个UTF-8编码的字符串
dos.writeUTF("你好");
dos.close();
}
public static void readData()throws IOException
{
DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
//可以直接读取基本数据类型
int num = dis.readInt();
boolean b = dis.readBoolean();
double d = dis.readDouble();
System.out.println("num="+num);
System.out.println("b="+b);
System.out.println("d="+d);
dis.close();
}
public static void writeData()throws IOException
{
DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
//可以直接写入基本数据类型
dos.writeInt(234);
dos.writeBoolean(true);
dos.writeDouble(9887.543);
dos.close();
}
ByteArrayInputStream:
用于操作字节数组的流对象
ByteArrayInputStream :在构造的时候,需要接收数据源,而且数据源是一个字节数组。
ByteArrayOutputStream: 在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组。
这就是数据目的地。
因为这两个流对象都操作的数组,并没有使用系统资源。
所以,不用进行close关闭。
用流的读写思想来操作数据。
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"));