File file = new File("F:\java\java_basis\code\java_basisprogram");
File file1 = new File("F:\java\java_basis\code\java_basisprogram\test01.txt");
//是否是目录
System.out.println(file.isDirectory());
//是否是文件
System.out.println(file.isFile());
System.out.println(file1.isDirectory());
System.out.println(file1.isFile());
//文件字节大小
System.out.println(file1.length());
//是否可执行
System.out.println(file1.canExecute());
//是否可读写
System.out.println(file1.canRead());
System.out.println(file1.canWrite());
//创建文件,删除文件
File file2 = new File("F:\java\java_basis\code\java_basisprogram\test02.txt");
file2.createNewFile();
file2.delete();
//创建临时文件
File file3 = File.createTempFile("hjatemp-", ".txt");
//jvm退出时自动删除
file3.deleteOnExit();
System.out.println(file3.getAbsolutePath());
System.out.println(file3.isFile());
//遍历所有的文件和目录名
String[] list = file.list();
for (int i = 0;i
输出
true
false
false
true
1025
true
true
true
C:UsersDELLAppDataLocalTemphjatemp-5624244916572313819.txt
true
.idea
java_basisprogram.iml
out
src
test01.txt
F:javajava_basiscodejava_basisprogram.idea
F:javajava_basiscodejava_basisprogramjava_basisprogram.iml
F:javajava_basiscodejava_basisprogramout
F:javajava_basiscodejava_basisprogramsrc
F:javajava_basiscodejava_basisprogramtest01.txt
F:javajava_basiscodejava_basisprogramtest01.txt
InputStream
要特别注意的一点是,InputStream并不是一个接口,而是一个抽象类,它是所有输入流的超类。这个抽象类定义的一个最重要的方法就是int read(),签名如下:
public abstract int read() throws IOException;
package com.hja;
import java.io.*;
public class TestIO_InputStream {
public static void main(String[] args) throws IOException {
byte[] data = {72,101,108,108,111,33};
try (ByteArrayInputStream stream = new ByteArrayInputStream(data)) {
int n;
while ( (n = stream.read()) != -1){
System.out.println((char)n);
}
}
// String s;
// try (InputStream input = new FileInputStream("F:\java\java_basis\code\java_basisprogram\test01.txt")) {
// int n;
// StringBuilder sb = new StringBuilder();
// while ((n = input.read()) != -1) {
// sb.append((char) n);
// }
// s = sb.toString();
// }
// System.out.println(s);
try (InputStream inputStream = new FileInputStream("F:\java\java_basis\code\java_basisprogram\test01.txt")) {
String s1 = readAsString(inputStream);
System.out.println(s1);
}
try(ByteArrayInputStream stream = new ByteArrayInputStream(data)){
String s = readAsString(stream);
System.out.println(s);
}
}
//封装方法
public static String readAsString(InputStream inputStream) throws IOException {
int n;
StringBuilder sb = new StringBuilder();
while ((n=inputStream.read()) != -1){
char c = (char) n;
sb.append(c);
}
return sb.toString();
}
}
OutputStream
和InputStream类似,OutputStream也是抽象类,它是所有输出流的超类。这个抽象类定义的一个最重要的方法就是void write(int b),签名如下:
public abstract void write(int b) throws IOException;
Filter模式
通过一个“基础”组件再叠加各种“附加”功能组件的模式,称之为Filter模式(或者装饰器模式:Decorator)。它可以让我们通过少量的类来实现各种功能的组合:
┌─────────────┐
│ InputStream │
└─────────────┘
▲ ▲
┌────────────────────┐ │ │ ┌─────────────────┐
│ FileInputStream │─┤ └─│FilterInputStream│
└────────────────────┘ │ └─────────────────┘
┌────────────────────┐ │ ▲ ┌───────────────────┐
│ByteArrayInputStream│─┤ ├─│BufferedInputStream│
└────────────────────┘ │ │ └───────────────────┘
┌────────────────────┐ │ │ ┌───────────────────┐
│ ServletInputStream │─┘ ├─│ DataInputStream │
└────────────────────┘ │ └───────────────────┘
│ ┌───────────────────┐
└─│CheckedInputStream │
└───────────────────┘
序列化
序列化是指把一个Java对象变成二进制内容,本质上就是一个byte[]数组。
为什么要把Java对象序列化呢?因为序列化后可以把byte[]保存到文件中,或者把byte[]通过网络传输到远程,这样,就相当于把Java对象存储到文件或者通过网络传输出去了。
- 可序列化的Java对象必须实现java.io.Serializable接口,类似Serializable这样的空接口被称为“标记接口”(Marker Interface);
- 反序列化时不调用构造方法,可设置serialVersionUID作为版本号(非必需);
- Java的序列化机制仅适用于Java,如果需要与其它语言交换数据,必须使用通用的序列化方法,例如JSON。
//序列化
public static void main(String[] args) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
try (ObjectOutputStream output = new ObjectOutputStream(buffer)) {
// 写入int:
output.writeInt(12345);
// 写入String:
output.writeUTF("Hello");
// 写入Object:
output.writeObject(Double.valueOf(123.456));
}
System.out.println(Arrays.toString(buffer.toByteArray()));
}
//反序列化
try (ObjectInputStream input = new ObjectInputStream(...)) {
int n = input.readInt();
String s = input.readUTF();
Double d = (Double) input.readObject();
}
Reader
Reader是Java的IO库提供的另一个输入流接口。和InputStream的区别是,InputStream是一个字节流,即以byte为单位读取,而Reader是一个字符流,即以char为单位读取:
InputStream Reader 字节流,以byte为单位 字符流,以char为单位 读取字节(-1,0~255):int read() 读取字符(-1,0~65535):int read() 读到字节数组:int read(byte[] b) 读到字符数组:int read(char[] c)
FileReader
FileReader是Reader的一个子类,它可以打开文件并获取Reader。
CharArrayReader
CharArrayReader可以在内存中模拟一个Reader,它的作用实际上是把一个char[]数组变成一个Reader,这和ByteArrayInputStream非常类似
StringReader
StringReader可以直接把String作为数据源,它和CharArrayReader几乎一样:
try (Reader reader = new StringReader("Hello")) {
}
InputStreamReader
既然Reader本质上是一个基于InputStream的byte到char的转换器,那么,如果我们已经有一个InputStream,想把它转换为Reader,是完全可行的。InputStreamReader就是这样一个转换器,它可以把任何InputStream转换为Reader。示例代码如下:
// 持有InputStream:
InputStream input = new FileInputStream("src/readme.txt");
// 变换为Reader:
Reader reader = new InputStreamReader(input, "UTF-8");
//解决中文乱码问题
try (Reader reader = new InputStreamReader(new FileInputStream("F:\java\java_basis\code\java_basisprogram\test03.txt"), "GB2312")) {
int i ;
StringBuilder sb = new StringBuilder();
while ((i = reader.read()) != -1) {
sb.append((char) i);
}
String s = sb.toString();
System.out.println(s);
}
Writer
FileWriter
FileWriter就是向文件中写入字符流的Writer。它的使用方法和FileReader类似:
try (Writer writer = new FileWriter("readme.txt", StandardCharsets.UTF_8)) {
writer.write('H'); // 写入单个字符
writer.write("Hello".toCharArray()); // 写入char[]
writer.write("Hello"); // 写入String
}
CharArrayWriter
CharArrayWriter可以在内存中创建一个Writer,它的作用实际上是构造一个缓冲区,可以写入char,最后得到写入的char[]数组,这和ByteArrayOutputStream非常类似:
try (CharArrayWriter writer = new CharArrayWriter()) {
writer.write(65);
writer.write(66);
writer.write(67);
char[] data = writer.toCharArray(); // { 'A', 'B', 'C' }
}
StringWriter
StringWriter也是一个基于内存的Writer,它和CharArrayWriter类似。实际上,StringWriter在内部维护了一个StringBuffer,并对外提供了Writer接口。
OutputStreamWriter
除了CharArrayWriter和StringWriter外,普通的Writer实际上是基于OutputStream构造的,它接收char,然后在内部自动转换成一个或多个byte,并写入OutputStream。因此,OutputStreamWriter就是一个将任意的OutputStream转换为Writer的转换器:
try (Writer writer = new OutputStreamWriter(new FileOutputStream("readme.txt"), "UTF-8")) {
// TODO:
}
package com.hja;
import java.io.*;
import java.nio.charset.StandardCharsets;
public class TestIO_Writer {
public static void main(String[] args) throws IOException {
try (Writer writer = new FileWriter("F:\java\java_basis\code\java_basisprogram\TestIO_Writer.txt")) {
writer.write(11);//直接写入int类型失败
writer.write(String.valueOf(11));
writer.write("hja");
writer.write("胡建安");
writer.write("hello".toCharArray());
}
try(Writer writer = new OutputStreamWriter(new FileOutputStream("F:\java\java_basis\code\java_basisprogram\TestIO_Writer2.txt"), "GB2312")){
writer.write(12);//直接写入int类型失败
writer.write(String.valueOf(12));
writer.write("hja");
writer.write("胡建安");
writer.write("hello".toCharArray());
}
}
}
PrintStream和PrintWriter
PrintStream是一种能接收各种数据类型的输出,打印数据时比较方便:
- System.out是标准输出;
- System.err是标准错误输出。
PrintWriter是基于Writer的输出。



