File
File:可以是文件,也可以是目录
读取文件并过滤
public static void main(String [] args) throws NoSuchFieldException, IllegalAccessException {
File path = new File("/Users/joker/Pictures/图片/个人");
String [] pictureList = path.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.substring(name.lastIndexOf("."),name.length()).equals(".JPG")?true:false;
}
});
for(String str : pictureList){
System.out.println(str);
}
}
.list方法返回目录下文件名的数组,可以加一个过滤参数进行过滤
list会为每一个文件名调用accept方法
File的一些方法
public static void main(String [] args) throws NoSuchFieldException, IllegalAccessException, IOException {
File path = new File("/Users/joker/Pictures/景色2");
Random random = new Random(1);
File newPath = new File(path.getParentFile().toString() + "/景色3");
newPath.mkdirs();
File [] files = path.listFiles();
for(File file : files){
System.out.println(file.getName());
System.out.println(file.getAbsoluteFile());
System.out.println(file.getAbsolutePath());
System.out.println(file.getCanonicalFile());
System.out.println(file.getFreeSpace());
System.out.println(file.getParent());
System.out.println(file.getParentFile());
System.out.println(file.getPath());
System.out.println(file.getTotalSpace());
System.out.println(file.getUsableSpace());
System.out.println(file.createNewFile());
System.out.println(file.toURI());
System.out.println(file.isFile());
System.out.println(file.isDirectory());
System.out.println(file.isHidden());
System.out.println(file.canRead());
System.out.println(file.canWrite());
System.out.println(file.canExecute());
file.renameTo(new File(newPath.getPath().toString() +"/景色" + random.nextInt(100000) +".jpg"));
System.out.println("**************************************");
}
}
file的一些操作
输入和输出
流:能产出数据的数据源对象,能接受数据的接收端对象
javaI/O分为输入和输出两个部分
任何Inputstream和Reader派生出的类都有read方法读取单个字节或字节数组
任何Outputstream和Writer派生出的类都有write方法写单个字节或字节数组
通常不会用到这些类,他们存在的意义就是被其他类使用
InputStream
把不同的产出数据的数据源当做InputStream
- ByteArrayInputStream:将内存缓冲区当inputstream使用
- StringBufferInputStream:将String作为inputStream
- FileInputStream:将文件作为inputStream
- PipedInputStream:实现管道化概念,多线程中数据源
- SequenceInputStream:两个InputStream合到一起
所有的这些inputStream可以结合FilterInputStream使用效果更好
OutputStream
OutputStream决定了输出所要去往的目标
- ByteArrayOutputStream:在内存中创建缓冲区,文件的数据送到缓冲区中
- FileOutputStream:输送到文件中
- PipedOutputStream:实现管道化概念,多线程中数据源
所有的OutputStream都可以结合FilterOutputStream使用效果更好
添加属性和有用的接口
FilterInputStream和FilterOutputStream提供了修饰器类接口以及控制输入和输出
通过FilterInputStream从InputStream中读取数据
几乎每次对输入都要进行缓冲,所以java把没有缓冲视为特殊情况
FilterInputStream类型:
- DataInputStream:配合DataOutputStream使用,可以读取基本数据类型
- BufferedInputStream:使用缓冲区,可以指定缓冲区大小
DataInputStream可以读取基本数据类型以及String,方法都是read开头
通过FilterOutputStream向OutputStream写入数据
与DataInputStream对应的DataOutputStream可以写入基本数据类型以及String,方法都是write开头
PrintStream是打印基本数据类型以及String,两个重要的方法:print和println
BufferedOutputStream每次写入都是使用缓冲区,而不是每次都进行实际的物理写作
- DataOutputStream
- PrintStream
- BufferedOutputStream
Reader和Writer
java1.1加入Reader和Writer不是取代InputStream和OutputStream,而是为了更好的处理16位的Unicode字符,Unicode用于国际化,而且java的char也使用的是Unicode
InputStream和OutputStream是面向8位字节的
Reader和Writer是面向16位字符的
尽量使用Reader和Writer,如果编译报错,就可能使用8位字节操作的InputStream和OutputStream
字节和字符:字节是存储容量的基本单位,1字节=8个二进制位。 字符是指字母、数字、汉字和各种符号。
java采用Unicode,俩个字节表示一个字符,char是一个字符就是两个字节
中文一个汉字是3个字节,英文一个字母是2个字节
public static void main(String [] args) throws NoSuchFieldException, IllegalAccessException, IOException {
String str = "你好hello";
System.out.println(str.getBytes().length);
}
11个字节
字节和字符装换
- InputStream--Reader
- OutputStream--Writer
- FileInputStream--FileReader
- FileOutputStream--FileWriter
- ByteArrayInputStream--CharReader
- ByteArrayOutputStream--CharWriter
- PipedInputStream--PipedReader
- PipedOutputStream--PipedWriter
字符还有StringReader和StringWriter
适配器的转换
- FilterInputStream--FilterReader
- FilterOutputStream--FilterWriter
- BufferedInputStream--BufferedReader
- BufferedOutputStream--BufferedWriter
- PringStream--PrintWriter
应该使用BufferedReader的readLine
自我独立的类
RandomAccessFile
从Object继承来的独立的类,可以在一个文件中前后移动
- getFilePointer:当前所处文件位置
- seek:移动到文件中新的位置
- length:文件最大的尺寸
第二个参数指示随机读(r)还是又读又写(rw)
典型的I/O流使用方式
组合很多,但可能只会用到几种
缓冲输入文件
打开文件用于字符输入的FileReader,参数可以是String或File
提高速度使用缓冲,并且提供readLine方法,使用BufferedReader构造器
public static void main(String [] args) throws NoSuchFieldException, IllegalAccessException, IOException {
BufferedReader in = new BufferedReader(new FileReader("/Users/joker/扩展程序/banner.txt"));
String s;
StringBuilder sb = new StringBuilder();
while ((s = in.readLine())!=null)
sb.append(s + "\n");
in.close();
System.out.println(sb);
}
需要添加换行,因为readLine不会加上换行,需要显示关闭流
基本的文件输出
FileWriter可以向文件写入数据
创建一个与指定文件链接的FileWriter
用BufferedWriter将其包装使用缓冲
public static void main(String [] args) throws NoSuchFieldException, IllegalAccessException, IOException {
BufferedWriter out = new BufferedWriter(new FileWriter("test_file"));
out.write("jjboy");
out.close();
}
显示关闭流
读写随机访问文件
public static void main(String [] args) throws NoSuchFieldException, IllegalAccessException, IOException {
RandomAccessFile file = new RandomAccessFile("test_file","rw");
System.out.println(file.readLine());
for (int i=0;i<10;i++){
System.out.println(file.readLine());
}
file.close();
}
实现对一个文件的读写(不好用)
标准I/O
程序使用单一信息流
实现程序之间的通信,把程序串联起来
从标准输入中读取
java提供了System .in,System.out,System.err
默认已经使用PringStream包装了System.out和System.err,所以我们可以直接使用
但是System .in没有任何包装,所以使用之前需要包装
public static void main(String [] args) throws NoSuchFieldException, IllegalAccessException, IOException {
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in)
);
String str;
while ((str = in.readLine())!= null && str.length() != 0){
System.out.println(str);
}
}
首先使用InputStreamReader转换System .in,然后使用BufferedReader强化输入
标准I/O重定向
- setIn(InputStream)
- setOut(PrintStream)
- setErr(PrintStream)
I/O重定向操作的是字节流
新I/O
缓冲器:可以放数据的在通道中行驶的车,可以定义一车能放多少数据
通道:运送车,write和read方法操作的都是车
唯一与通道交互的缓冲器:ByteBuffer
对字节操作的FileInputStream,FileOutputStream和RandomAccessFile可以产生FileChannel
private static final int SIZE = 1024;
public static void main(String [] args) throws NoSuchFieldException, IllegalAccessException, IOException {
FileChannel in = new FileInputStream("test_file").getChannel();
FileChannel out = new FileOutputStream("test_file").getChannel();
FileChannel randomAccess = new RandomAccessFile("test_file","rw").getChannel();
out.write(ByteBuffer.wrap("some text".getBytes()));
out.close();
ByteBuffer buffer = ByteBuffer.allocate(SIZE);
in.read(buffer);
buffer.flip();
while (buffer.hasRemaining()){
System.out.println((char)buffer.get());
}
in.close();
}
使用getChannel方法返回一个FileChannel
wrap方法往车里放数据
buffer.hasRemaining:车里面有数据
flip:车随时准备接受数据
public static void main(String [] args) throws NoSuchFieldException, IllegalAccessException, IOException {
FileChannel out = new FileOutputStream("test_file").getChannel();
BufferedReader in = new BufferedReader(new FileReader("test_file"));
out.write(ByteBuffer.wrap("abcd\nefgh\nigklmno\npqrst".getBytes()));
out.close();
String s ;
StringBuilder sb = new StringBuilder();
while ((s = in.readLine())!=null)
sb.append(s + "\n");
in.close();
System.out.println(sb);
}
uio写数据,Reader读数据
private static final int SIZE = 1024;
public static void main(String [] args) throws NoSuchFieldException, IllegalAccessException, IOException {
FileChannel in = new FileInputStream(args[0]).getChannel(),
out = new FileOutputStream(args[1]).getChannel();
ByteBuffer buffer = ByteBuffer.allocate(SIZE);
while (in.read(buffer) != -1){
buffer.flip();
out.write(buffer);
buffer.clear();
}
in.close();
out.close();
}
文件内容复制
clear:清空车,以便能够再次装数据
private static final int SIZE = 1024;
public static void main(String [] args) throws NoSuchFieldException, IllegalAccessException, IOException {
FileChannel in = new FileInputStream(args[0]).getChannel(),
out = new FileOutputStream(args[1]).getChannel();
ByteBuffer buffer = ByteBuffer.allocate(SIZE);
in.transferTo(0,in.size(),out);
//out.transferFrom(in,0,in.size());
}
使用transferTo或者transferFrom能将两个管道连接起来
文件加锁
文件锁对操作系统中的其他进程是可见的
public static void main(String [] args) throws NoSuchFieldException, IllegalAccessException, IOException {
FileChannel in = new FileInputStream(args[0]).getChannel();
FileLock fl = in.tryLock();
fl.release();
}
对FileChannel调用lock或者tryLock方法返回文件锁
tryLock:非阻塞式的,如果当前文件已经被锁住,马上退出方法
lock:阻塞式IDE,如果当前文件已经被锁着,就会等待,直到可以获得文件锁
release:释放锁
压缩
压缩是按字节方式操作的
压缩类是从InputStream和OutputStream继承来的
常用的压缩类:
- ZipInputStream
- ZipOutputStream
- GZipInputStream
- GZipOutputStream
将文件压缩成Zip格式或GZip格式
GZip
Gzip接口简单,对单个数据流使用Gzip比较合适
public static void main(String [] args) throws NoSuchFieldException, IllegalAccessException, IOException {
BufferedReader in = new BufferedReader(new FileReader("test_file"));
BufferedOutputStream out = new BufferedOutputStream(
new GZIPOutputStream(
new FileOutputStream("file.gz")
)
);
String s;
while ((s = in.readLine())!=null){
out.write(s.getBytes());
}
in.close();
out.close();
BufferedReader reader = new BufferedReader(
new InputStreamReader(
new GZIPInputStream(
new FileInputStream("file.gz")
)
)
);
StringBuilder sb = new StringBuilder();
while ((s = reader.readLine())!=null){
sb.append(s + "\n");
}
System.out.println(sb);
reader.close();
}
使用Gzip封装写入字节流对文件进行压缩
使用Gzip封装读取字符流读取压缩文件
可以字符流读压缩文件,只能字节流写压缩文件
Zip
Zip支持的操作更全面一点
两种校验类型(Checksum):
- Adler32:快
- CRC32:慢一点,但是准确
public static void main(String [] args) throws NoSuchFieldException, IllegalAccessException, IOException {
ZipOutputStream zip = new ZipOutputStream(new CheckedOutputStream(new FileOutputStream("file.zip"),new Adler32()));
BufferedOutputStream out = new BufferedOutputStream(zip);
BufferedReader in = new BufferedReader(
new FileReader("test_file")
);
Random random = new Random(1);
zip.setComment("zip_test");
String s;
while ((s = in.readLine()) != null){
zip.putNextEntry(new ZipEntry(String.valueOf(random.nextInt(100))));
out.write(s.getBytes());
out.flush();
}
in.close();
out.close();
}
使用Zip对多文件进行压缩
setComment:写注释
压缩没一个文件之前都需要putNextEntry
CheckedOutputStream:设置校验方式
GZip和Zip可以压缩任何东西,不限于文件,可以是通过网络发送的数据
java档案文件
Zip也被应用于JAR(java档案文件)
JDK自带的jar程序可以自动压缩文件
典型方法:
jar cf myJarFile.jar *.class
创建了一个名为myJarFile的jar文件并包含了当前目录下多有的class文件
对象序列化
java对象序列化:实现了Serializeable接口的对象可以转换成一个字节序列,并且可以从这个字节序列可以完全恢复成原来的对象
序列可以通过网络传输,从Windows电脑到Unix电脑
两个特性:
- 使得存在其他电脑上的对象完全可以被自己使用
- 向远程对象发消息时使用序列化参数和返回值
对象序列化是基于字节的
序列化:创建对象的OutputStream,用ObjectOutputStream封装,然后调用writeObject方法
反序列化:创建对象的InputStream,用ObjectInputStream封装,调用readObject方法
序列化把对象中的别的对象的引用也保存了,依次类推形成对象网