Java IO流(详解)
Posted 364.99°
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java IO流(详解)相关的知识,希望对你有一定的参考价值。
- 1. File
- 2. IO流
1. File
文件: 保存数据的地方。
1. 创建
构造器:
new File
- (String pathName) // 根据路径构建一个 File对象
- (File parent, String child) // 根据父目录文件 + 子路径构建
- (String parent, String child) // 根据父目录 + 子路径构建
创建对象:
createNewFile
(String pathName) —— 目录必须存在,才能创建文件
如果 D:\\Study\\file_demo\\ 路径不存在,会抛出异常:java.io.IOException: 系统找不到指定的路径 。
public static File create_01(String path)
File file = new File(path);
try
file.createNewFile();
catch (IOException e)
e.printStackTrace();
return file;
public static void main(String[] args)
String path = "D:\\\\Study\\\\file_demo\\\\demo1.txt";
File file = create_01(path);
(File parent, String child)
如果 D:\\Study\\file_demo\\ 路径不存在,会抛出异常:java.io.IOException: 系统找不到指定的路径 。
public static File create_02(File parent, String child)
File file = new File(parent, child);
try
file.createNewFile();
catch (IOException e)
e.printStackTrace();
return file;
public static void main(String[] args)
File parent = new File("D:\\\\Study\\\\file_demo\\\\");
String path = "demo2.txt";
File file = create_02(parent, path);
(String parent, String child)
如果 D:\\Study\\file_demo\\ 路径不存在,会抛出异常:java.io.IOException: 系统找不到指定的路径 。
public static File create_03(String parent, String child)
File file = new File(parent, child);
try
file.createNewFile();
catch (IOException e)
e.printStackTrace();
return file;
public static void main(String[] args)
String parent = "D:\\\\Study\\\\file_demo\\\\";
String child = "demo3.txt";
File file = create_03(parent, child);
注意:
- new File 只是在内存中创建了一个对象
- createNewFile 才是在磁盘上创建了一个文件
2. 操作
1. 获取文件信息
方法:
- getName
- getAbsolutePath
- getParent
- length
- exists
- isFile
- isDirectory
public static Map<String, String> getFileInfo(File file)
Map<String, String> info = new HashMap<>();
info.put("文件名", file.getName());
info.put("文件绝对路径", file.getAbsolutePath());
info.put("文件父级目录", file.getParent());
info.put("文件大小(byte)", String.valueOf(file.length()));
info.put("文件是否存在", file.exists() + "");
info.put("是否是文件", file.isFile() + "");
info.put("是否是目录", String.valueOf(file.isDirectory()));
return info;
public static void main(String[] args)
File file = new File("D:\\\\Study\\\\file_demo\\\\demo1.txt");
getFileInfo(file).forEach((k, v) ->
System.out.println(k + ":" + v);
);
2. 目录创建/删除
方法:
- mkdir
创建一级目录 - mkdirs
创建多级目录 - delete
删除空目录/文件
注意: Java中,目录也被当做文件。
public static void create_01(String path)
File file = new File(path);
String flagE = null;
String flagM = null;
String flagMs = null;
if (file.exists())
flagE = file.delete() ? "文件删除成功" : "文件删除失败";
else
flagE = "文件不存在";
System.out.println(flagE);
boolean isMk = file.mkdir();
flagM = isMk ? "一级目录创建成功" : "一级目录创建失败";
System.out.println(flagM);
if (!isMk)
flagMs = file.mkdirs() ? "多级目录创建成功" : "多级目录创建失败";
System.out.println(flagMs);
public static void main(String[] args)
String path = "D:\\\\Study\\\\file_demo\\\\test";
create_01(path);
2. IO流
IO: Input/Output,处理数据传输的技术。
Stream: 流,Java中的数据的输入/输出都以流的方式进行。
- 分类(数据单位)
- 字节流(1 byte)—— InputStream、OutputStream
- 字符流(1 字符)—— Reader、Writer
- 分类(流向)
- 输入流
- 输出流
- 分类(角色)
- 节点流
- 处理流/包装流
1. FileInputStream
1. 简单使用
public static String readFile_01(String path)
FileInputStream inputStream = null;
StringBuilder sb = new StringBuilder();
int curr = 0;
try
inputStream = new FileInputStream(path);
while ((curr = inputStream.read()) != -1)
// read ———— 每次读取 1byte, 读取完毕就返回 -1
sb.append((char) curr + "");
catch (IOException e)
e.printStackTrace();
finally
try
inputStream.close();
catch (IOException e)
e.printStackTrace();
return sb.toString();
public static void main(String[] args) throws IOException
String path = "D:\\\\Study\\\\file_demo\\\\user.txt";
System.out.println(readFile_01(path));
注意:
- read 每次读取 1byte,读取完毕返回 -1
- 每次使用完流,都得使用 close 关闭流,避免资源浪费
- 使用 FileInputStream 读取中文可能会出现中文乱码问题
- 原因:
FileInputStream 每次读取大小为 1byte = 8bit,在 GBK 编码模式下,每个中文为 2bit,但在 UTF-8 编码 模式下,每个中文为 3bit,显然不能刚好装进一个 byte 数组。 - 解决方案:
- 使用 FileReader
- 使用 read(byte b[]),并将 byte 数组的容量设置足够大
这个方法就是自定义每次读取的字节数组的大小
- 原因:
2. 读取中文
思路: 声明一个容量足够大的 byte 数组(能一次性吧文件读完),然后使用 public int read(byte b[]) 读取文件(会将文件内容存入 b[],并返回 b.length)。
public static String readFile_01(String path)
FileInputStream inputStream = null;
StringBuilder sb = new StringBuilder();
// 用一个足够大的 byte 数组来装下内容
byte [] bytes = new byte[83];
int readLen = 0;
try
inputStream = new FileInputStream(path);
// 返回值是读取的字节长度
while ((readLen = inputStream.read(bytes)) != -1)
// read ———— 每次读取 1byte, 读取完毕就返回 -1
sb.append(new String(bytes, 0, readLen));
catch (IOException e)
e.printStackTrace();
finally
try
inputStream.close();
catch (IOException e)
e.printStackTrace();
return sb.toString();
public static void main(String[] args) throws IOException
String path = "D:\\\\Study\\\\file_demo\\\\user.txt";
System.out.println(readFile_01(path));
2. FileOutputStream
1. 简单使用
write
-
write(int b)
-
write(byte b[])
-
write(byte b[], int off, int len)
public static void write_01(String path, String words)
FileOutputStream outputStream = null;
try
outputStream = new FileOutputStream(path);
//
outputStream.write(words.getBytes());
catch (IOException e)
e.printStackTrace();
finally
try
outputStream.close();
catch (IOException e)
e.printStackTrace();
public static void main(String[] args)
String words = "在龟友百货上班,规规矩矩地纳税。";
String path = "D:\\\\Study\\\\file_demo\\\\user.txt";
write_01(path, words);
注意:
- 直接这样 write 会覆盖掉之前的内容
- 进行写操作的时候,文件可以不存在,但目录必须存在
2. 追加写入
在初始化 FileOutputStream 的时候,传入一个参数 true,表明——在文件末尾追加内容。
outputStream = new FileOutputStream(path, true);
3. 文件拷贝
需求: 将如图所示的四种文件拷贝到另外一个文件夹:
步骤: 输入流(读取到内存)→ 输出流(写入到磁盘)
读取部分数据,就写入磁盘,不能一次性读完再写(防止内存不够)。
public static void copy(String resPath, String tarPath)
FileInputStream inputStream = null;
FileOutputStream outputStream = null;
byte []bytes = new byte[1024 * 1024]; // 一次读 1MB
int len = 0;
try
inputStream = new FileInputStream(resPath);
outputStream = new FileOutputStream(tarPath);
while ((len = inputStream.read(bytes)) != -1)
outputStream.write(bytes, 0, len); // 这里必须使用此方法,防止文件读取时没装完
catch (IOException e)
e.printStackTrace();
finally
try
if (inputStream != null)
inputStream.close();
if (outputStream != null)
outputStream.close();
catch (IOException e)
e.printStackTrace();
public static void main(String[] args)
String res1 = "D:\\\\Study\\\\file_demo\\\\resource\\\\pic.jpg";
String res2 = "D:\\\\Study\\\\file_demo\\\\resource\\\\user.txt";
String res3 = "D:\\\\Study\\\\file_demo\\\\resource\\\\电锯人5.mp4";
String res4 = "D:\\\\Study\\\\file_demo\\\\resource\\\\周杰伦 - 我是如此相信.mp3";
String tar1 = "D:\\\\Study\\\\file_demo\\\\target\\\\pic.jpg";
String tar2 = "D:\\\\Study\\\\file_demo\\\\target\\\\user.txt";
String tar3 = "D:\\\\Study\\\\file_demo\\\\target\\\\电锯人5.mp4";
String tar4 = "D:\\\\Study\\\\file_demo\\\\target\\\\周杰伦 - 我是如此相信.mp3";
copy(res1, tar1);
copy(res2, tar2);
copy(res3, tar3);
copy(res4, tar4);
4. FileReader
1. 简单使用
public static String readFile_02(String path)
FileReader reader = null;
StringBuilder sb = new StringBuilder();
int curr = 0;
try
reader = new FileReader(path);
while (true)
if ((curr = reader.read()) == -1) break;
sb.append((char) curr + "");
catch (IOException e)
e.printStackTrace();
finally
if (reader != null)
try
reader.close();
catch (IOException e)
e.printStackTrace();
return sb.toString();
public static void main(String[] args)
String path = "D:\\\\Study\\\\file_demo\\\\target\\\\user.txt";
System.out.println(readFile_02(path));
注意: 因为 FileReader 是一个字符一个字符地读取的,所以不存在中文乱码问题。
2. 提高读取速度
按照上面的写法,每次只读取一个字符,效率太低,为了提高读取效率,可以使用这个方法:public int read(char cbuf[])
public static String readFile_02(String path)
FileReader reader = null;
StringBuilder sb = new StringBuilder();
char []chars = new char[8]; // 一次读取 8 个字符
《java基础知识》Java IO流详解