目录
一、File 类
二、RandomAccessFile
三、流类
四、字节流
4.1 、InputStream
4.2、OutputStream
五、字符流
5.1、Reader
5.2、Writer
六、管道流
七、ByteArrayInputStream 和 ByteArrayOutputStream
八、System.out 和 System.in
九、打印流
十、DataOutputStream 和 DataInputStream
十一、SequenceInputStream
十二、字节流与字符流的转换
十三、IO 包中的类层次关系图
13.1 字节输入流
13.2 字节输入流
13.3 字符输入流
13.4 字符输出流
十四、字符编码
十五、序列化
Java 开发中,如果程序需要把数据保存到文件中,就可以使用 I/O 输入输出技术。一般应用程序都需要与外部设备进行数据交换,常见的磁盘、键盘和屏幕等都属于外部设备,在程序中,键盘被用做文件输入,显示器被用做文件输出。Java 语言定义了许多专门负责各种方式的输入输出,这些都被放在 Java.io 包。
一、File 类
File 类是 IO 包处理文件的代表。通过 File 类能够完成创建、删除文件、重命名文件、判断文件的读写权限以及文件是否存在,设置和查询文件最近修改时间等操作。
File 方法 (JDK1.8)
方法 | 描述 |
File(String pathname) | 只有一个参数的构造方法 |
File(String parent, String child) | 两个参数的构造方法 |
File(File parent, String child) | 两个参数的重写构造方法 |
File(URI uri) | 参数为URI构造方法 |
String getName() | 获取名称 |
String getParent() | 获取上一级路径 |
File getParentFile() | 获得上一级路径 ,返回File对象 |
String getPath() | 获取路径 |
boolean isAbsolute() | 判断是否绝对路径 |
String getAbsolutePath() | 获取绝对路径 |
File getAbsoluteFile() | 获取路径获取绝对路径信息,返回File |
String getCanonicalPath() throws IOException | 返回该抽象路径名的规范路径名字符串 |
File getCanonicalFile() throws IOException | 返回该抽象路径名的规范形式,返回File对象 |
URL toURL() throws MalformedURLException | 将文件对象转换为URL(统一资源定位符) |
public URI toURI() | 将文件对象转换为URL(统一资源标识符) |
boolean canRead() | 判断是否可读权限 |
boolean canWrite() | 判断是否可写权限 |
boolean exists() | 判断目录或者文件是否存在 |
boolean isDirectory() | 判断否是一个目录 |
boolean isFile() | 判断是否一个文件 |
boolean isHidden() | 判断文件或者目录是否隐藏 |
long lastModified() | 获取文件或者目录的修改时间 |
long length() | 获取文件内容长度 |
boolean createNewFile() throws IOException | 创建新文件,已经存在不会再创建 |
boolean delete() | 根据路径删除文件或目录,删除目录时,目录有文件,删除失败 |
void deleteOnExit() | 请求删除操作(虚拟机正常退出的时候删除操作) |
String[] list() | 获取路径下的文件、目录 |
String[] list(FilenameFilter filter) | 根据文件过滤器获取路径下的文件、目录,参数文件过滤器(文件名以 .jar 或者 .zap结尾) |
File[] listFiles() | 根据路径获取文件或者目录,返回为File[],需要详细信息可以用这个方法 |
File[] listFiles(FilenameFilter filter) | 根据文件过滤器获取路径下的文件、目录。参数是一个文件过滤器。 返回为File[] |
File[] listFiles(FileFilter filter) | 根据路径创建目录,只能是单级目录 |
boolean mkdir() | 根据路径创建目录(可以多级目录),创建之前会判断文件是否存在,创建成功返回true ,失败返回false |
boolean mkdirs() | 目录或者文件重命名,重命名成功返回true,失败返回false 目录或者文件重命名,重命名成功返回true,失败返回false |
boolean renameTo(File dest) | 目录或者文件重命名,重命名成功返回true,失败返回false 目录或者文件重命名,重命名成功返回true,失败返回false |
boolean setLastModified(long time) | 设置文件或者目录修改时间 |
boolean setReadOnly() | 设置文件或者目录只读 |
boolean setWritable(boolean writable, boolean ownerOnly) | 设置是否可以可写 。 第一个参数 true 可写 第二个参数 所属人 ,true拥有者 ,false全部用户 |
boolean setWritable(boolean writable) | 设置文件或者目录可写 |
boolean setReadable(boolean readable, boolean ownerOnly) | 设置是否可以读 。 第一个参数 true 可读 第二个参数 所属人 ,true拥有者 ,false全部用户 |
boolean setReadable(boolean readable) | 设置是否可读 |
boolean setExecutable(boolean executable, boolean ownerOnly) | 设置是否有可执行权限 |
boolean setExecutable(boolean executable) | 设置是否有可执行文件以及所属用户(系统支持生效)第一个参数: true 可以执行 false不可以执行,返回值true 设置成功 第二个参数: true拥有者 ,false全部用户 |
boolean canExecute() | 判断是否可以执行 |
static File[] listRoots() | 列出可用的文件系统根目录 |
long getTotalSpace() | 获取分区大小,返回单位字节 |
void getFreeSpace() | 获取分区可用大小,返回单位字节 |
long getUsableSpace() | 获取磁盘用户可使用大小,返回单位字节 |
static File createTempFile(String prefix, String suffix, File directory) | 创建临时文件 |
static File createTempFile(String prefix, String suffix) throws IOException | 创建临时文件 |
Path toPath() | 把File对象转换Path对象 |
示例
import sun.misc.JarFilter;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Path;
import java.time.Instant;
public class Main {
public static void main(String[] args) throws Exception {
//只有一个参数的构造方法
//file_1();
// 两个参数的构造方法
//file_2();
// 两个参数的重写构造方法
//file_3();
// 参数为URI构造方法
//file_4();
// 获取名称
// getName();
//获取上一级路径
//getParent();
//获得上一级路径 ,返回File对象
//getParentFile();
// 获取路径
//getPath();
//判断是否绝对路径
//isAbsolute();
//获取绝对路径
//getAbsolutePath();
// 获取路径获取绝对路径信息,返回File
//getAbsoluteFile();
// 返回该抽象路径名的规范路径名字符串
// getCanonicalPath();
// 返回该抽象路径名的规范形式,返回File对象
//getCanonicalFile();
// 将文件对象转换为URL(统一资源定位符)
//toURL();
// 将文件对象转换为URL(统一资源标识符)
//toURI();
//判断是否可读权限
//canRead();
//判断是否可写权限
// canWrite();
//判断目录或者文件是否存在
//exists();
//判断否是一个目录
//isDirectory();
//判断是否一个文件
// isFile();
//判断文件或者目录是否隐藏
//isHidden();
//获取文件或者目录的修改时间
//lastModified();
//获取文件内容长度
//length();
//创建新文件,已经存在不会再创建
//createNewFile();
//根据路径删除文件或目录,删除目录时,目录有文件,删除失败
//delete();
//请求删除操作(虚拟机正常退出的时候删除操作)
//deleteOnExit();
// 获取路径下的文件、目录
//list();
// 根据文件过滤器获取路径下的文件、目录,参数文件过滤器(文件名以 .jar 或者 .zap结尾)
//list1();
//根据路径获取文件或者目录,返回为File[],需要详细信息可以用这个方法
//listFiles();
// 根据文件过滤器获取路径下的文件、目录。参数是一个文件过滤器。 返回为File[]
//listFiles1();
//根据路径创建目录,只能是单级目录
//mkdir();
//根据路径创建目录(可以多级目录),创建之前会判断文件是否存在,创建成功返回true ,失败返回false
//mkdirs();
// 目录或者文件重命名,重命名成功返回true,失败返回false 目录或者文件重命名,重命名成功返回true,失败返回false
//renameTo();
//设置文件或者目录修改时间
//setLastModified();
//设置文件或者目录只读
// setReadOnly();
// 设置文件或者目录可写
// setWritable();
// 设置是否可以读 。 第一个参数 true 可读 第二个参数 所属人 ,true拥有者 ,false全部用户
// setWritable1();
//设置是否有可执行权限
//setExecutable();
// 设置是否有可执行文件以及所属用户(系统支持生效)第一个参数: true 可以执行 false不可以执行,返回值true 设置成功 第二个参数: true拥有者 ,false全部用户
//setExecutable1();
//判断是否可以执行
// canExecute();
// 列出可用的文件系统根目录
//listRoots();
//获取分区大小
//getTotalSpace();
// 获取分区可用大小
//getFreeSpace();
//获取磁盘用户可使用大小,返回单位字节
//getUsableSpace();
//创建临时文件
//createTempFile();
// 创建临时文件.重新方法
//createTempFile1();
//把File对象转换Path对象
//toPath();
}
/**
* 构造方法
* 只有一个参数,路径(路径可以是一个文件路径,也可以是一个文件路径)。路径可以相对路径也可以绝对路径
* File(String pathname)
*/
static void file_1() {
File f = new File("E:\\file\\1.txt");
System.out.println(f); // E:\file\1.txt
}
/**
* 构造方法
* 第一个参数父路径
* 第二个参数子路径
* File(String parent, String child)
*/
static void file_2() {
File f1 = new File("E:\\file", "1.txt");
System.out.println(f1); //E:\file\1.txt
}
/**
* 构造方法
* 第一个参数 File对象(文件父路径 File)
* 第二个参数 子路径
* File(File parent, String child)
*/
static void file_3() {
File f3 = new File("E:\\file");
File f4 = new File(f3, "1.txt");
System.out.println(f4);// /E:\file\1.txt
}
/**
* 构造方法
* 参数是URI类
* File(URI uri)
*/
static void file_4() {
File f5 = null;
try {
f5 = new File(new URI("file:///E://file/1.txt"));
} catch (URISyntaxException e) {
e.printStackTrace();
}
System.out.println(f5);
}
/**
* 获取名称
* String getName()
*/
static void getName() {
File f = new File("E:\\file/1.txt");
System.out.println(f.getName());
}
/**
* 获得上一级路径
* String getParent()
*/
static void getParent() {
File f = new File("E:\\file/1/");
System.out.println(f.getParent());
}
/**
* 获得上一级路径 ,返回File对象
* File getParentFile()
*/
static void getParentFile() {
File f = new File("E:\\file/1/");
System.out.println(f.getParentFile());
}
/**
* 获取路径
* String getPath()
*/
static void getPath() {
File f = new File("E:\\file/a/a.txt");
System.out.println(f.getPath());
}
/**
* 判断是否绝对路径
* boolean isAbsolute()
*/
static void isAbsolute() {
File f = new File("E:\\file/a/a.txt");
System.out.println(f.isAbsolute());
}
/**
* 获取绝对路径
* String getAbsolutePath()
*/
static void getAbsolutePath() {
File f = new File("E:\\file/a/a.txt");
System.out.println(f.getAbsolutePath());
}
/**
* 获取路径获取绝对路径信息,返回File
* File getAbsoluteFile()
*/
static void getAbsoluteFile() {
File f = new File("E:\\file/a/a.txt");
System.out.println(f.getAbsoluteFile());
}
/**
* 返回该抽象路径名的规范路径名字符串
* String getCanonicalPath() throws IOException
*/
static void getCanonicalPath() {
File f = new File("E:\\file/a/a.txt");
try {
System.out.println(f.getCanonicalPath());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 返回该抽象路径名的规范形式,返回File对象
* File getCanonicalFile() throws IOException
*/
static void getCanonicalFile() {
File f = new File("E:\\file/a/a.txt");
try {
System.out.println(f.getCanonicalFile());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 将文件对象转换为URL(统一资源定位符)
* URL toURL()
*/
static void toURL() {
File f = new File("E:\\file/a/a.txt");
URL url = null;
try {
url = f.toURL();
} catch (MalformedURLException e) {
e.printStackTrace();
}
System.out.println(url);
}
/**
* 将文件对象转换为URI(统一资源标识符)
*/
static void toURI() {
File f = new File("E:\\file/a/a.txt");
URI uri = f.toURI();
System.out.println(uri);
}
/**
* 判断是否可读权限
* boolean canRead()
*/
static void canRead() {
File f = new File("E:\\file/a/a.txt");
System.out.println(f.canRead());
}
/**
* 判断是否可写权限
* boolean canWrite()
*/
static void canWrite() {
File f = new File("E:\\file/a/a.txt");
System.out.println(f.canWrite());
}
/**
* 判断目录或者文件是否存在
* boolean exists()
*/
static void exists() {
File f = new File("E:\\file/a/a.txt");
System.out.println(f.exists());
}
/**
* boolean isDirectory()
*/
static void isDirectory() {
File f = new File("E:\\file/a/a.txt");
System.out.println(f.isDirectory());
}
/**
* 判断是否一个文件
* boolean isFile()
*/
static void isFile() {
File f = new File("E:\\file/a/a.txt");
System.out.println(f.isFile());
}
/**
* 判断文件或者目录是否隐藏
* boolean isHidden()
*/
static void isHidden() {
File f = new File("E:\\file/a/a.txt");
System.out.println(f.isHidden());
}
/**
* 获取文件或者目录的修改时间
* long lastModified()
*/
static void lastModified() {
File f = new File("E:\\file/a/a.txt");
System.out.println(f.lastModified());
}
/**
* 获取文件内容长度
* long length()
*/
static void length() {
File f = new File("E:\\file/a/a.txt");
System.out.println(f.length());
}
/**
* 创建新文件,已经存在不会再创建
* boolean createNewFile() throws IOException
*/
static void createNewFile() {
File f = new File("E:\\file/a/a.txt");
try {
System.out.println(f.createNewFile());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 根据路径删除文件或目录,删除目录时,目录有文件,删除失败
* boolean delete()
*/
static void delete() {
File f = new File("E:\\file/a/a.txt");
System.out.println(f.delete());
}
/**
* 请求删除操作(虚拟机正常退出的时候删除操作)
* <p>
* void deleteOnExit()
*/
static void deleteOnExit() {
File f = new File("E:\\file/a/a.txt");
f.deleteOnExit();
}
/**
* 获取路径下的文件、目录
* String[] list()
*/
static void list() {
File f8 = new File("E:\\file");
String[] list = f8.list();
if (null != list && list.length > 0) {
for (int i = 0; i < list.length; i++) {
System.out.println(list[i]);
}
}
}
/**
* 根据文件过滤器获取路径下的文件、目录,参数文件过滤器(文件名以 .jar 或者 .zap结尾)
* String[] list(FilenameFilter filter)
*/
static void list1() {
File f9 = new File("E:\\file");
FilenameFilter ff = new JarFilter();
String[] list9 = f9.list(ff);
if (null != list9 && list9.length > 0) {
for (int i = 0; i < list9.length; i++) {
System.out.println(list9[i]);
}
}
}
/**
* 根据路径获取文件或者目录,返回为File[],需要详细信息可以用这个方法
* File[] listFiles()
*/
static void listFiles() {
File f9 = new File("E:\\file");
File[] list10 = f9.listFiles();
if (null != list10 && list10.length > 0) {
for (int i = 0; i < list10.length; i++) {
System.out.println(list10[i]);
}
}
}
/**
* 根据文件过滤器获取路径下的文件、目录。参数是一个文件过滤器。 返回为File[]
* File[] listFiles(FilenameFilter filter)
*/
static void listFiles1() {
FilenameFilter ff = new JarFilter();
File f9 = new File("E:\\file");
File[] list11 = f9.listFiles(ff);
if (null != list11 && list11.length > 0) {
for (int i = 0; i < list11.length; i++) {
System.out.println(list11[i]);
}
}
}
/**
* 根据路径创建目录,只能是单级目录
* boolean mkdir()
*/
static void mkdir() {
File f11 = new File("E:\\file");
System.out.println(f11.mkdir());
}
/**
* 根据路径创建目录(可以多级目录),创建之前会判断文件是否存在,创建成功返回true ,失败返回false
* boolean mkdirs()
*/
static void mkdirs() {
File f11 = new File("E:\\file");
System.out.println(f11.mkdirs());
}
/**
* 目录或者文件重命名,重命名成功返回true,失败返回false
* boolean renameTo(File dest)
*/
static void renameTo() {
File f13 = new File("E:\\file/");
File f14 = new File("E:\\file1/");
System.out.println(f13.renameTo(f14));
}
/**
* 设置文件或者目录修改时间
* boolean setLastModified(long time)
*/
static void setLastModified() {
File f15 = new File("E:\\file/");
Instant i = Instant.now(); // 获取当前时间,i.toEpochMilli()获取当前毫秒值,返回值long
System.out.println(f15.setLastModified(i.toEpochMilli()));
}
/**
* 设置文件或者目录只读
* boolean setReadOnly()
*/
static void setReadOnly() {
File f15 = new File("E:\\file/");
System.out.println(f15.setReadOnly());
}
/**
* 设置是否可以写
* boolean setWritable(boolean writable)
*/
static void setWritable() {
File f15 = new File("E:\\file/");
System.out.println(f15.setWritable(true));
}
/**
* 设置是否可写以及所有者
* 第一个参数 true 是可以读 false 不可以写
* 第二个参数 true拥有者 ,false全部用户
*/
static void setWritable1() {
File f15 = new File("E:\\file/");
System.out.println(f15.setWritable(true, true));
}
/**
* 设置是否可以读
* boolean setReadable(boolean readable)
*/
static void setReadable() {
File f15 = new File("E:\\file/");
System.out.println(f15.setReadable(true));
}
/**
* 设置是否有可执行权限
* boolean setExecutable(boolean executable)
*/
static void setExecutable() {
File f15 = new File("E:\\file/");
System.out.println(f15.setExecutable(true));
}
/**
* 设置是否有可执行文件以及所属用户(系统支持生效)第一个参数: true 可以执行 false不可以执行,返回值true 设置成功 第二个参数: true拥有者 ,false全部用户
* boolean setExecutable(boolean executable, boolean ownerOnly)
*/
static void setExecutable1() {
File f15 = new File("E:\\file/");
System.out.println(f15.setExecutable(true, true));
}
/**
* 判断是否可以执行
* boolean canExecute()
*/
static void canExecute() {
File f = new File("E:\\file/");
System.out.println(f.canExecute());
}
/**
* 列出可用的文件系统根目录
* static File[] listRoots()
*/
static void listRoots() {
File[] fileArr = File.listRoots();
for (int i = 0; i < fileArr.length; i++) {
// System.out.println(fileArr[i]);
}
}
/**
* 获取分区大小,返回单位字节
* long getTotalSpace()
*/
static void getTotalSpace() {
File f = new File("E:\\file/a/a.txt");
long l = f.getTotalSpace() / 1024 / 1024 / 1024;// 单位G
System.out.println(l);
}
/**
* 获取分区可用大小,返回单位字节
* long getFreeSpace()
*/
static void getFreeSpace() {
File f = new File("E:\\file/a/a.txt");
long l = f.getFreeSpace() / 1024 / 1024 / 1024;// 单位G
System.out.println(l);
}
/**
* long getUsableSpace()
* 获取磁盘用户可使用大小,返回单位字节
*/
static void getUsableSpace() {
File f = new File("E:\\file/a/a.txt");
long l = f.getUsableSpace() / 1024 / 1024 / 1024;// 单位G
System.out.println(l);
}
/**
* 创建临时文件
* static File createTempFile(String prefix, String suffix)
* 第一个参数:文件前缀
* 第二个参数:文件后缀,null的话值为 .tmp
*/
static void createTempFile() {
try {
File f = File.createTempFile("zzq", null);
System.out.println(f);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 创建临时文件
* 第一个参数:文件前缀
* 第二个参数:文件后缀,null的话值为 .tmp
* 第三个参数:文件对象,可以理解为临时文件生成的目录
*/
static void createTempFile1() {
try {
File ff = new File("E:\\file");
File f = File.createTempFile("zzq", null, ff);
System.out.println(f);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 把File对象转换Path对象
* Path toPath()
*/
static void toPath() {
File f = new File("E:\\file");
Path path = f.toPath();
System.out.println(path);
}
}
二、RandomAccessFile
RandomAccessFile 类是 Java 语言中功能丰富的文件访问类。提供了许多文件方法的方法。RandomAccessFile 类支持 “随机访问” 方式,可以跳到文件的任意位置读取和写数据。在访问一个文件的时候,不想把文件从头到尾读取,而是希望像访问一个数据库一样方法一个文本文件,可以使用 RandomAccessFile 类就是比较好的选择。
示例
import java.io.RandomAccessFile;
public class Main {
public static void main(String[] args) throws Exception {
/**
* E://file/1.txt 内容为 12t
*/
RandomAccessFile r = new RandomAccessFile("E://file/1.txt","rw");
r.skipBytes(2); // 跳过2个字节
System.out.println( r.readLine()); // t
}
}
三、流类
Java 的流建立在 4 个抽象类的基础上:InputStream、OutputStream、Reade 和 Writer。
其中 InputStream、OutputStream 称为字节流。Reade 和 Writer 称为字符流。
字节流和字符流形参分离的层次结构,处理字符或者字符串使用字符流,处理字节或者二进制对象使用字节流。
一般操作文件流时,不管字节流还是字符流都是可以安装以下方式进行。
1、使用 File 类找到一个文件。
2、通过 File 类对象去实例化字节流或者字符流的子类。
3、进行字节流或者字符流的读取操作。
4、关闭流文件。
四、字节流
字节流为处理字节输入与输出提供了丰富的环境。一个字节流可以和其他任何类型的对象并用,包括二进制数据。
4.1 、InputStream
InputStream 称为字节输入流,该类的所有方法在出错的都会引发一个 IOException 异常。
InputStream 扩展方法:
方法 | 描述 |
int read() throws IOException | 如果下一个字节可读取则返回一个整型,没有可读返回-1 |
int read(byte b[]) throws IOException | 试图读取到内容到 buffer 中,并返回读取的字节数,没有可读返回-1 |
int read(byte b[], int off, int len) throws IOException | 试图读从off开始,长度为 len 的内容到 buffer 中,并返回读取的字节数,没有可读返回-1 |
skip(long n) throws IOException | 忽略n个输入字节,并且返回忽略的字节数 |
int available() throws IOException | 返回当前可读的输入字节数 |
void mark(int readlimit) | 在输入流当前放置一个标识 |
void reset() throws IOException | 重新设置输入指针到先前设置的标志处 |
boolean markSupported() | 判断是否支持mark()/reset() ,支持返回true |
示例
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class Main {
public static void main(String[] args) throws Exception {
InputStream input = null;
try {
input = new FileInputStream("E:\\file/1.txt");
定义1024个字节大小的缓冲区
byte[] b = new byte[1024];
int n;
while ((n = input.read(b)) != -1) { // 读取到缓冲区
System.out.println(new String(b, 0, n));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != input) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
4.2、OutputStream
OutputStream称为字节输出流。该类的所有方法在出错的情况下会引发一个 IOException 异常。
OutputStream 扩展方法:
方法 | 描述 |
void write(int b) throws IOException | 向输出流写入单个字节 |
void write(byte b[]) throws IOException | 向输出流写一个完整的字节数组 |
void write(byte b[], int off, int len) throws IOException | 向输出流写入以 off 开始 长度为 len 的 字节b数组内容 |
示例
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
OutputStream out = null;
try {
out = new FileOutputStream("E:\\file/1.txt",true);
//把字符串转成字节数组
byte[] b = "Hello world".getBytes();
// 将 byte 数组写到文件中
out.write(b);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != out) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
五、字符流
当需要直接处理字符串等就可以使用字符流处理。
5.1、Reader
Reader 是字符流的输入抽象类,该类的所有方法在出错的情况下会引发一个 IOException 异常。
Reader 常用方法:
方法 | 描述 |
int read() throws IOException | 如果调用的输入流下一个字符可读则返回一个整型,没有可读返回-1 |
int read(char cbuf[]) throws IOException | 读取 cbuf字符数组中的字符并且返回字符数,没有可读返回-1 |
int read(char cbuf[], int off, int len) throws IOException | 读取 以off开始并且长度为len的cbuf字符数组中的字符并且返回字符数,没有可读返回-1 |
long skip(long n) throws IOException | 跳过n个输入字符,并且返回跳过的字符设置输入指针到先前设立的标志处 |
boolean ready() throws IOException | 如果下一个输入请求不等待返回true,否则返回false |
boolean markSupported() | 判断流是否支持mark()/reset(),支持返回true,否则返回false |
void mark(int readAheadLimit) throws IOException | 在输入流当前设置一个标志 |
void reset() throws IOException | 重新设置输入指针到先前设置的标志处 |
示例
import java.io.FileReader;
import java.io.Reader;
public class Main {
public static void main(String[] args) throws Exception {
Reader r = new FileReader("E:\\file/1.txt");
char[] c = new char[1024];
int i = 0;
try {
i = r.read(c);
String s= new String(c,0,i );
System.out.println(s);
}catch (Exception e){
}
}
}
5.2、Writer
Writer 是字符流的输出抽象类。该类的所有方法在出错的情况下会引发一个 IOException 异常
Writer 常用方法:
方法 | 描述 |
void write(int c) throws IOException | 向字符输入流写入c个字符 |
void write(char cbuf[]) throws IOException | 向字符输入流写入cbuf字符数组内容 |
void write(char cbuf[], int off, int len) throws IOException | 向调用的输出流写入数组cbuf , 以 off开始 长度为len的内容 |
void write(String str) throws IOException | 向调用输出流写str内容 |
void write(String str, int off, int len) throws IOException | 向调用输出流写str内容,以off开始,长度为len的内容 |
示例
import java.io.FileWriter;
import java.io.Writer;
public class Main {
public static void main(String[] args) throws Exception {
;
try( Writer w = new FileWriter("E:\\file/1.txt",true)){
w.write("Hello World");
}
}
}
六、管道流
管道流用于连接两个线程间的通信。管道流也分为字节流(PipedInputStream、PipedOutputStream)与字符流(PipedReader、PipedWriter)两种类型。
例如,一个生产线程与一个消费线程就可以通过管道流通信。
示例
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
Producer p = new Producer();
Consumer c = new Consumer();
PipedOutputStream out = p.getInstance();
PipedInputStream input = c.getInstance();
out.connect(input); // 输入与输出流连接管道
p.start(); // 启动生产者线程
c.start(); // 启动消费者线程
}
}
// 生产者
class Producer extends Thread{
private PipedOutputStream out = new PipedOutputStream();
public PipedOutputStream getInstance(){
return out;
}
@Override
public void run() {
String str = new String ("Producer说:消费者你好!");
try {
// 写入内容
out.write(str.getBytes());
}catch (IOException e){
e.printStackTrace();
}finally {
try {
// 关闭资源
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// 消费者
class Consumer extends Thread{
private PipedInputStream input = new PipedInputStream();
public PipedInputStream getInstance(){
return input;
}
@Override
public void run() {
String s = null;
byte[] byteArr = new byte[1024];
int len = 0;
try {
len = input.read(byteArr);
s = new String(byteArr,0,len);
System.out.println("Consumer收到信息----->:"+s);
} catch (IOException e) {
e.printStackTrace();
}
}
}
七、ByteArrayInputStream 和 ByteArrayOutputStream
ByteArrayInputStream 包含一个内部缓冲区,该缓冲区包含流中读取字节。简单点来说,内部缓冲区就是一个字节数组,而 ByteArrayInputStream 本质就是一个通过字节数组来实现的。
ByteArrayOutputStream 中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据。
示例
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
byte[] byteArr = "Hello World".getBytes(); // 把字符串转内存块
ByteArrayInputStream input = new ByteArrayInputStream(byteArr);
ByteArrayOutputStream out = new ByteArrayOutputStream();
transfrom(input,out);
byte[] outResult = out.toByteArray();
System.out.println(new String(outResult));
}
public static void transfrom(ByteArrayInputStream input,ByteArrayOutputStream out){
int c = 0;
try {
while ( (c =input.read()) != -1){
int C = (int)Character.toUpperCase((char)c);
out.write(C);
}
}catch (Exception e){
e.printStackTrace();
}
}
}
八、System.out 和 System.in
Java 定义了两个特殊的流对象:System.out 和 System.in 。System.in 对应键盘,属于 InputStream 类型,程序可以使用 System.in 可以读取键盘上输入的数据。
System.out 属性 PrintStream 类型,PrintStream 是 OutputStream 的一个子类,程序使用
System.out 可以将数据输出到显示器上或者控制台。
示例
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
while (true) {
int c = System.in.read();// 键盘输入
System.out.print( Character.toUpperCase((char)c) +"\t"); // 控制台输出
}
}
}
九、打印流
PrintStream 类提供了一系列的 print 和 println方法,可以实现将基本数据类型的格式转换成字符串输出。程序中大量用到 "System.out.println" 语句中的 “System.out” 就是PrintStream 类的一个实例对象。
实例:向控制台输出 "Hello World" 字符串。
示例
import java.io.PrintWriter;
public class Main {
public static void main(String[] args) throws Exception {
PrintWriter out = null;
// 通过System.out 对 PrintWriter 实例化
out = new PrintWriter(System.out);
out.print("Hello World");
out.close();
}
}
示例:向文件写入 "Hello World" 内容 。
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
public class Main {
public static void main(String[] args) throws Exception {
PrintWriter out = null;
// 通过System.out 对 PrintWriter 实例化
out = new PrintWriter(System.out);
File f = new File("E:\\file/1.txt");
out = new PrintWriter(new FileWriter(f));
out.write("Hello World");
out.close();
}
}
十、DataOutputStream 和 DataInputStream
当需要对数据做一定格式的时候,可以使用DataOutputStream 和 DataInputStream 处理。
示例
import java.io.*;
public class Main {
/**
*
* 订单信息: 产品名称:鞋子, 数量:10, 价格:18.99
* 订单信息: 产品名称:袜子, 数量:10, 价格:9.22
* 订单信息: 产品名称:杯子, 数量:20, 价格:14.22
* 订单信息: 产品名称:衣服, 数量:39, 价格:5.22
* 订单信息: 产品名称:裤子, 数量:40, 价格:4.21
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
write();
read();
}
public static void write() throws Exception {
DataOutputStream out = new DataOutputStream(new FileOutputStream("E:\\file/1.txt"));
// 价格
double[] prices = {18.99,9.22,14.22,5.22,4.21};
// 数目
int[] units = {10,10,20,39,40};
// 产品名称
String[] descs = {"鞋子","袜子","杯子","衣服","裤子"};
for(int i=0; i<prices.length;i++ ){
// 价格写入
out.writeDouble(prices[i]);
out.writeChar('\t');
// 写入数目
out.writeInt(units[i]);
out.writeChar('\t');
// 写入产品
out.writeChars(descs[i]);
out.writeChar('\n');
}
out.close();
}
public static void read() throws Exception {
DataInputStream input = new DataInputStream(new FileInputStream("E:\\file/1.txt"));
double price;
int unit;
StringBuffer desc;
double total = 0.0;
try {
while (input.available() != 0){
// 读书价格
price = input.readDouble();
// 跳过tab
input.readChar();
// 读出数目
unit = input.readInt();
// 跳过tab
input.readChar();
char chr;
// 读出产品
desc = new StringBuffer();
while((chr = input.readChar()) != '\n'){
desc.append(chr);
}
System.out.println("订单信息:"+" 产品名称:"+desc+",\t数量:"+unit+", \t价格:"+price);
total = total +unit * price;
}
}catch (Exception e){
e.printStackTrace();
}
System.out.println("中共需要:"+total+"元");
input.close();
}
}
十一、SequenceInputStream
SequenceInputStream 可以实现两个文件合并操作。
示例:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.SequenceInputStream;
public class Main {
public static void main(String[] args) throws Exception {
// 声明两个文件读取流
FileInputStream input1 = null ,input2 = null;
// 声明一个合并流
SequenceInputStream s = null;
FileOutputStream out = null;
try {
// 构造两个被读入文件的文件
File inputF1 = new File("E:\\file/1.txt");
File inputF2 = new File("E:\\file/2.txt");
// 构造一个输出文件
File outF3 = new File("E:\\file/3.txt");
input1 = new FileInputStream(inputF1);
input2 = new FileInputStream(inputF2);
// 将两个输入流合并一个输入流
s = new SequenceInputStream(input1,input2);
out = new FileOutputStream(outF3);
int c;
while ((c=s.read() )!= -1){
out.write(c);
}
}catch (Exception e){
}finally {
input1.close();
input2.close();
s.close();
out.close();
}
}
}
十二、字节流与字符流的转换
Java 支持字节流和字符流,但有时需要在字节流和字符流之间转换。InputStreamReader 和
OutputStreamWriter ,这两个类是字节流和字符流之间转换的类。
示例
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
/**
* 字节流 System.in
* 转换流 InputStreamReader
* 字符缓存流 BufferedReader
*/
BufferedReader readerBuf = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter writeBuf = new BufferedWriter(new OutputStreamWriter(System.out));
String str = null;
while (true) {
System.out.print("\n请输入内容:");
str = readerBuf.readLine();
System.out.print("\n显示内容:");
writeBuf.write(str);
writeBuf.flush();
}
}
}
十三、IO 包中的类层次关系图
13.1 字节输入流
InputStream类
13.2 字节输入流
InputStream类
13.3 字符输入流
Reader 类
13.4 字符输出流
Writer
十四、字符编码
对于我们使用的计算机而言,只能认识数字,计算机软件里一切都是用数字来表示。
最开始计算机在美国使用,当时所用到的字符也就是在键盘上的一些字符和少数几个特殊的字符,每一个字符都用一个数字表示,一个字节所能表示的数字范围足以容纳所有字符,实际上表示这些字符的数字的字节最高位(bit)都为 0 ,也就是说这些数字都在 0 到 127 之间,例如字符 a 对应数字 97,b 对应数字98 等,这种字符与数字对应的编码固定下来后,这套编码规则称为 ASCII码(美国标准信息交换码)。
随着计算机在其他国家的逐渐应用与普及,许多国家都把本地的字符集引入了计算机,这大大扩展了计算机中字符的范围。一个字符所能表示的数字范围不能容纳所有的中文汉字的。中国将每一个中文字符都是用两个中文字符的数字来表示,原有的 ASCII 码 字符的编码保持不变,仍用一个字节表示。为了将一个中文字符与两个 ASCII 码字符区别,中文字符的每个字节的最高位(bit)都是 1,中国大陆为每一个中文字符都指定了一个对应的数字,并作为标准的编码固定了下来,这套编码则称 GBK(国标码) 后面在GBK基础上做了些中文字符(包括繁体)进行了编码,并且命名了GBK2312 。换句话说 GBK 是 GBK2312 的子集。使用中文的国家和地区有很多,同样一个字符例如 “中国” 的 “中” 在中国大陆的编码是十六进制的 D6D0,而台湾地区的编码规则是十六进制的 A4A4 ,台湾地区规则称 BIG5(大五码)。
在一个国家的本地化系统中出现一个字符,到另外一个国家本地化系统中,看不到原始字符,而是乱码。
为了解决各个国家和地区使用各自不同本地化编码带来的不便,人们将全世界所有的编码进行了统一,称之为 Unicode 编码。
示例
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class Main {
public static void main(String[] args) throws Exception {
// byte[] b = "你好,Java".getBytes("ISO-8859-1"); // 乱码
byte[] b = "你好,Java".getBytes();
OutputStream out = new FileOutputStream(new File("E:\\file/1.txt"));
out.write(b);
out.close();
/**
* file.encoding=UTF-8
*/
System.getProperties().list(System.out);
}
}
十五、序列化
是指将对象转换成二进制数据流的一种实现。通过序列化,可以很方便实现对象的传输与保存。
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
File file = new File("E:\\file/1.txt") ;
serialize(file);
desSerialize(file);
}
/**
* 序列化对象
* @param f
* @throws Exception
*/
public static void serialize(File f) throws Exception {
OutputStream outFile = new FileOutputStream(f) ;
ObjectOutputStream oos = new ObjectOutputStream(outFile);
Person p = new Person("张三",22);
oos.writeObject(p);
oos.close();
}
/**
* 反序列化
* @param f
* @throws Exception
*/
public static void desSerialize(File f) throws Exception {
InputStream inputFile = new FileInputStream(f) ;
ObjectInputStream ois = new ObjectInputStream(inputFile);
Person p = (Person)ois.readObject();
System.out.println(p.toString());
}
}
class Person implements Serializable{
private Integer age;
private String name;
public Person(String name,Integer age) {
this.name = name;
this.age = age;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}