java021
file讲解:文件和目录路径名的抽象表示形式
IO流操作的是数据,而数据一般是以文件的表现形式。
File类:用来将文件或者文件夹封装成对象
方便对文件与文件夹的属性信息进行操作
file对象可以作为参数传递给流的构造函数
File类常见的方法:
1. 文件的创建:
boolean createNewFile():在指定位置下创建文件,如果该文件已经存在,则不创建,
返回false.和输出流不一样,输出流对象一建立创建文件,而且文件已经存在。
boolean mkdir():创建文件夹
boolean mkdirs():创建多级文件夹
2. 删除文件:
boolean delete():删除失败返回false,如果文件正在被使用,则删除不了
void deleteOnExit() 在程序退出时删除指定文件。
3. 判断:
boolean exists():文件是否存在
因为仅仅通过File file = new File("1.txt");中的1.txt是不能判断
file是否是文件还是文件夹,因为1.txt可以作为文件还是文件夹的名称使用
isFile():判断是否是文件,前提条件要先createNewFile创建
isDirectory():判断是否是目录,前提要先mkdir,mkdirs创建
exists():测试此抽象路径名表示的文件或目录是否存在。前提条件要先createNewFile创建
isHidden():判断是否是隐藏文件;
isAbsolute():判断是否是绝对路径。
3. 获取信息:
getPath():获取路径
getAbsolutePath():获取绝对路径
getPerent():获取绝对路径中的父目录,如果获取的是相对路径,返回null,
如果相对路径中有上一层目录那么该目录就是返回的结果。
listRoots():返回系统的盘符:c: d:..
list(“目录”):列出所有在该目录下的文件和文件夹(包括隐藏文件)
假如“目录”是文件类型则会抛异常(空指针,因为文件没有目录就没有包含其他文件
或文件夹当遍历时就会出现异常)
list(FilenameFilter filter):列出通过了过滤器的文件
4.修改:
file1.renameTo(file2)://此方法类似于剪切,但是假如在目标中有被重名的文件那么会重命名不成功
5.遍历文件夹
listFile中存在递归:
· package xyxysjxy.io.file;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.List;
public class FileTest1
{
public static void main(String[]
args) throws Exception {
method6();
}
public static void method6() throws Exception
{
File file = new File("I:\\tupian" );
List<File> files = new ArrayList<File>();
listMenus(files, file);
System. out.println(files.size());
FileWriter fw = new FileWriter("I:\\tupian\\1.txt" );
BufferedWriter bw = new BufferedWriter(fw);
for (File f : files) {
bw.write(f.getAbsolutePath());
bw.newLine();
bw.flush();
}
}
// 列出文件夹的清单文件
public static void listMenus(List<File>
filess, File file) {
if (file.isDirectory()) {
File files[] = file. listFiles();
if (files != null &&
files.length != 0) {
for (File f : files) {
if (f.isFile()) {
filess.add(f);
} else {
listMenus(filess, f);
}
}
}
filess.add(file);
}
}
// 目录的删除,写递归啊,觉得就应该把要递归语句当作已经完成了。继续写接下来要执行的语句
public static void deleteDirFiles(File
file) {
if (file.isDirectory()) {
File files[] = file. listFiles();
if (files != null &&
(files.length != 0)) {
for (File f : files) {
if (f.isFile())
System. out
.println(file.toString() + "dir" +
f.delete());
else
deleteDirFiles(f);
}
System. out.println(file.toString() + "dir" +
file.delete());
} else
System. out.println(file.toString() + "dir" +
file.delete());
}
}
// 递归调用遍历文件
public static void diGui(File
file, int level) {
if (file.isDirectory()) {
System. out.println(cengJi(level++) + file);
File files[] = file. listFiles();
if (files != null &&
(files.length != 0))
for (File file2 : files) {
diGui(file2, level);
}
}
System. out.println(cengJi(level++) + file);
level--;
}
public static String
cengJi(int level) {
StringBuilder sb = new StringBuilder();
for (int l
= 0; l < level; l++)
sb.append( " ");
return sb.toString() + "|--" ;
}
public static void method5() throws Exception
{
File file1 = new File("F:\\" );
// String files[] = file1.list();
// File files[] = file1.listFiles();
String files[] = file1.list( new FilenameFilter()
{
@Override
// 接口回调方式: dir是this,name是文件名(在该目录下的通过fs.list())
public boolean accept(File
dir, String name) {
System. out.println("dir:" +
dir + "name:" + name);
if (name.endsWith(".mp3" ))
{
return true ;
}
return false ;
}
});
for (String file : files) {
System. out.println("file:" +
file);
}
}
public static void method4() throws Exception
{
File file1 = new File("e:\\1.txt" );
// file1.createNewFile();
File file2 = new File("f:\\2.txt" );
// 此方法类似于剪切,但是假如在目标中有被重名的文件那么会重命名不成功
System. out.println(file2.renameTo(file1));
}
public static void method3() throws Exception
{
File file1 = new File("f:\\a\\1.txt" );
// file1.createNewFile();// 必须是已经存在的路径
// file1.mkdirs ();
System. out.println(file1.exists());
System. out.println(file1.isFile());
System. out.println(file1.isDirectory());
System. out.println(file1.isAbsolute());
}
public static void method2() throws Exception
{
File file1 = new File("f:\\a\\b\\c" , "1.txt");
file1.mkdirs();
file1.createNewFile();
// file1.deleteOnExit();
// file1.delete();
}
public static void method1()
{
File file1 = new File("f:\\a\\b\\c\\1.txt" );
File file2 = new File("f:\\a\\b\\c\\d" , "2.txt");
File file3 = new File("f:" +
File.separator + "a" +
File.separator
+ "b" + File.separator + "c" +
File.separator + "d"
+ File. separator + "e" , "3.txt" );
File d = new File("f:\\a\\b\\c\\d\\e\\f" );
File file4 = new File(d, "f.txt" );
sop(file1);
sop(file2);
sop(file3);
sop(file4);
}
public static void sop(File
file) {
System. out.println(file.toString());
}
}
7. Properties是hashTable的子类
也就是说它具备集合的特点,而且它里面存储的键值对都是字符串
是集合中和IO技术相结合的集合容器
该对象的特点:可以用于键值对形式的配置文件
8. PrintStream 和 PrintWriter
打印流:(输出流)
该流提供了打印方法,可以将各种数据类型的数据都原样打印。
字节打印流:
PrintStream
构造函数可以接收的参数类型:
1. file对象。File
2. 字符串路径。String
3. 字节输出流。outputStream
字符打印流:
printWriter
构造函数可以接收的参数类型:
1.file对象。File
2. 字符串路径。String
3. 字节输出流。OutputStream
4. 字符输出流。Writer
9. SequenceInputStream 合并流
package xyxysjxy.io;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;
public class SequenceInputStreamTest
{
public static void main(String[]
args) throws Exception {
FileInputStream fr1 = new FileInputStream("f:\\1.txt");
FileInputStream fr2 = new FileInputStream( "f:\\2.txt");
FileInputStream fr3 = new FileInputStream("f:\\3.txt");
FileInputStream fr4 = new FileInputStream("f:\\4.txt");
PrintStream ps = new PrintStream("f:\\5.txt" );
Vector< FileInputStream> v = new Vector<FileInputStream>();
v.add(fr1);
v.add(fr2);
v.add(fr3);
v.add(fr4);
Enumeration< FileInputStream> e = v.elements();
SequenceInputStream sis = new SequenceInputStream(e);
BufferedInputStream bts = new BufferedInputStream(sis);
byte b[] = new byte[1024];
int len = 0;
while ((len = bts.read(b)) != -1) {
ps.write(b, 0, len);
ps.flush();
}
sis.close();
ps.close();
System. out.println("合并流成功了
!!!" );
}
}
9. 切割文件
package xyxysjxy.io;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
public class SplitFiles
{
public static void main(String[]
args) throws IOException {
FileInputStream fis = new FileInputStream("f:\\Brandy
- So Sick.mp3" );
BufferedInputStream bis = new BufferedInputStream(fis);
byte b[] = new byte[1024
* 1024];
int len = 0;
int count = 0;
while ((len = bis.read(b)) != -1) {
FileOutputStream fos = new FileOutputStream("f:\\" +
++count
+ ".part");
fos.write(b, 0, len);
fos.close();
}
bis.close();
System. out.println("分割成功i哦" );
ArrayList<FileInputStream> fileInputStreams = new ArrayList<FileInputStream>();
for (int i
= count; i > 0; i--) {
FileInputStream fiss = new FileInputStream("f:\\" +
i + ".part");
fileInputStreams.add(fiss);
}
final Iterator<FileInputStream> is = fileInputStreams.iterator();
Enumeration<FileInputStream> es = new Enumeration<FileInputStream>()
{
@Override
public boolean hasMoreElements()
{
return is.hasNext();
}
@Override
public FileInputStream nextElement() {
return is.next();
}
};
SequenceInputStream sis = new SequenceInputStream(es);
FileOutputStream fos = new FileOutputStream("f:\\merge.mp3" );
byte b2[] = new byte[1024];
int len2 =
0;
while ((len2 =
sis.read(b2)) != -1) {
fos.write(b2, 0, len2);
fos.flush();
}
fos.close();
sis.close();
}
}
10 操作对象:对象需要序列化(实现标记接口(没有要你去实现的接口)) 标记
ObjectInputStream与ObjecOutputStream (成对使用)
通过serializable来标识对象是否出自哪个类中,而且序列化UID是通过类成员来计算出来的
所以当你改变类中的成员后(反序列化会报标识不一致)
但是自己也可以自定义一个标识 而且更改了其中的成员一样可以识别(序列化 反序列化)
静态是不能被序列化的(因为序列化针对是对象存在于堆中,而静态的存在共享区)要想非静态的成员
不能被序列化可以用(transient)修饰。
11 管道流:输出和输入可以直接连接,通过结合线程使用
PipedInputStream 和 PipeOutputStream
管道输入流应该连接到管道输出流;管道输入流提供要写入管道输出流的所有数据字节。通常,数据由某个线程从
PipedInputStream
对象读取,并由其他线程将其写入到相应的PipedOutputStream
。不建议对这两个对象尝试使用单个线程,因为这样可能死锁线程。管道输入流包含一个缓冲区,可在缓冲区限定的范围内将读操作和写操作分离开。如果向连接管道输出流提供数据字节的线程不再存在,则认为该管道已损坏。
package xyxysjxy.io;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class PipeStreamTest
{
public static void main(String[]
args) {
//创建两个管道流发现并没有目的地,说明内存中的流
PipedInputStream pi = new PipedInputStream();
PipedOutputStream po = new PipedOutputStream();
try {
po.connect(pi);
} catch (IOException e) {
e.printStackTrace();
}
Thread t1 = new Thread(new PipeStreamTest().new Write(po));
Thread t2 = new Thread(new PipeStreamTest().new Read(pi));
t1.start();
t2.start();
}
class Write implements Runnable
{
private PipedOutputStream po ;
public Write(PipedOutputStream po) {
this.po =
po;
}
public void run()
{
try {
po.write( "管道流来了" .getBytes());
po.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Read implements Runnable
{
PipedInputStream pi;
public Read(PipedInputStream pi) {
this.pi =
pi;
}
@Override
public void run()
{
byte[] b = new byte[1024];
try {
int len = pi .read(b);
System. out.println(new String(b,0,len));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
12 RandomAccessFile://
随机访问文件,自身具备读写方法。可以实现多线程下载功能。
线程1|-----| 线程2|-----| 线程3|-----| 线程4|-----| 线程5|-----|........把一个文件切割成多段
通过skipByte(int x)seek(int x)来达到随机访问
该类不是IO体系中的子类,而是直接继承自Object,但是IO包中的成员,因为他有读写功能。
内部封装了一个数组,而且通过指针对数组元素进行操作。可以通过getFilePointer获取指针位置,
同时可以通过seek改变指针位置。之所以有读写功能是因为内部封装了输入输出流。
而且还有操作文件还有模式:r ,rw,rws,rwd 四种
当模式为r时,假如读文件不存在会抛异常不会自动创建;当模式为rw时没有就创建,有也不覆盖文件。
13 DataOutputStream 和 DataInputStream 操作基本数据类型
用它writeUTF()写必须用readUTF()读这里的UTF和UTF-8有所不同
14 ByteArrayInputStream 和 ByteArrayOutputStream//带缓冲区,可变长度
ByteArrayInputStream
1.
ByteArrayInputStream
包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪
read
方法要提供的下一个字节。关闭 ByteArrayInputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException
2.在构造的时候,需要接收数据源,而且数据源是一个字节数组。
ByteArrayOutputStream
1.此类实现了一个输出流,其中的数据被写入一个 byte 数组。
缓冲区会随着数据的不断写入而自动增长。可使用
toByteArray()
和toString()
获取数据。2.在构造的时候,不用定义数据目的,因为该对象中已经封装了一个数组为目的地。
因为这两个流对象都是操作数组,并没有关联系统资源,所以不用关流。
操作字符数组:CharArrayReader 和 CharArrayReader
操作字符串:StringReader 和 StringWriter
write()向下转为一个字节写入,read()阻塞式读出
字符编码:
PrintStream PrintWriter
OutputStreamWriter InputStreamReader
编码:字符串变成字节数组 String-->byte[] str.getBytes(charsetName)
解码:字节数组变成字符串byte[]-->String new String(byte[],charsetName);