Java I/O流复习(一)—File类、字节流、字节缓冲流
来源:互联网 发布:黑马程序员训练营 编辑:程序博客网 时间:2024/06/05 05:25
Java I/O流复习(一)—File类、字节流、字节缓冲流
1. File类
1.1 File类作用
- 文件可认为是相关记录或放在一起的数据的集合。文件一般存放在存储介质上:硬盘、u盘、光盘、软盘、云盘等。
- java.io.File 类是专门对文件进行操作的类。(只能对文件本身进行操作,不能对文件内容操作)
- File类是“文件和目录路径名的抽象表示”。 而不是指文件的内容(IO)。路径就是字符串
- File类定义了一些与平台无关的方法操作,如:创建、删除文件和重命名等。
- Java中目录被看成是一个特殊的文件。 File.listFiles()方法可以返回目录中所有的子目录和文件。
- 在unix下路径分隔符为(/),而在windos中则是为(\),在java中可以正确的处理不同系统中的分隔符。注意:从1.5开始在java中可以统一使用(/)来作为路径分隔符。
1.2 File类的构造方法
public File(String pathname); 以pathname为路径创建File对象,如果pathname是相对路径,则是相对于Java的系统属性user.dir中的路径。(对eclipse创建的java工程来说,就是该工程的根目录。)
public File(File dir,String name);
根据f 抽象路径名和 child 路径名字符串创建一个新 File 实例。
1.3 File类文件属性
1.3.1 属性:
- public static final String separator 分隔符 存储了当前系统的名称分隔符,在 UNIX 和Mac系统上,此字段的值为 ‘/’;在 Windows 系统上,它为 ‘\’;为了程序的跨平台特性,文件的路径应该用这个属性值来代表。
- public static final char pathSeparator 存储了当前系统默认路径分割符号,在 UNIX 和Mac系统上,此字段的值为’:’,Windows系统是’;’。
1.4 使用File类对文件进行访问
[^提示]: 创建文件的时候是相对路径就返回相对路径,是绝对路径就返回绝对路径。
Scanner sc = new Scanner(System.in); while (true) { System.out.println("请输入一个路径"); String next = sc.next(); File file = new File(next); if (file.exists()) { String name = file.getName(); String absolutePath = file.getAbsolutePath(); File parentFile = file.getParentFile(); parentFile.getParent(); boolean canRead = file.canRead(); boolean canWrite = file.canWrite(); long lastModified = file.lastModified(); Date date = new Date(lastModified); System.out.println("文件名"+" "+"文件的路径"+" "+"文件目录"+" "+"是否可读"+" "+"最后一次修改时间"); System.out.println(name+" "+absolutePath+" "+parentFile+" "+canRead+" "+date.toString()); break; }else { System.out.println("你输入的文件不存在"); } }
1.5 使用File类对文件进行操作
1.6 使用File类浏览目录中的文件和子目录
课堂练习:使用 递归算法 打印出目录(文件夹)中所有文件与目录(包括目录内部的文件和目录)。
``java
public class Main5 {
private static void listChilds(File f){
if (f==null)
return;
System.out.println(f.getPath());
if (f.isFile())
return;
File[] files = f.listFiles();
for (File file : files)
listChilds(file);
}
private static File file = new File(“F:\\java和HTML等”);
public static void findFile(File file) {
if (file.isDirectory()) {
File[] listFiles = file.listFiles();
if (listFiles==null||listFiles.length==0) {
return;
}else {
for (File f : listFiles) {
System.out.println(f);
if (f.isDirectory()) {
findFile(f);//递归
}
}
}
}
}
public static void main(String[] args) {
findFile(file);
}
}
2. IO概念和种类:
2.1 什么是IO流?
IO指的是 Input/Output,IO流:输入输出流。 统称为数据流。(IO Stream)
在Java程序中,对于数据的输入 / 输出操作以流的方式进行;流是从起源到接收的有序数据。JDK提供了各种各样的Stream 类,用以获取不同种类的数据;
IO流的作用就是对文件数据的读(输入)和写(输出)。
2.2 流的作用和原理?
3. IO流的种类:
3.1 输入流、输出流
- 输入流:程序可以从中读取数据的流(流入程序的流)
- 输出流:程序能向其中写入数据的流 (从程序流出的流)
3.2 字节流、字符流
- 字节流:以字节为单位传输数据的流
- 字符流:以字符为单位传输数据的流
3.3 节点流、处理流
- 节点流:用于直接操作目标设备的流
- 处理流:是对一个已存在的流的连接和封装,通过对数据的处理为程序提供更为强大、灵活的读写功能。
3.4 IO流的分类图:
4. 字节输入流:
4.1 InputStream类的常用方法
- available() 方法,获取与之关联的文件剩余可读的字节数。
int read() 方法,读取输入流。读取输入流的下一个字节,返回一个0-255之间的int类型整数。如果到达流的末端,返回-1。
int read(byte[] b) 方法,读取输入流。读取多个字节,存入字节数组b,返回实际读入的字节数。如果到达流的末端,返回-1。
int read (byte[] b, int off, int len); 方法,读取输入流。每次读取len个字节,存入字节数组b,从off下标开始存储。如果到达流的末端,返回-1。
- close() 方法,关闭当前流,释放与该流相关的资源,防止资源泄露。在带资源的try语句中将被自动调用。关闭流之后还试图读取字节,会出现IOException异常。
4.2 InputStream类的子类:文件输入流FileInputStream
FileInputStream 用于读取本地文件中的字节数据,继承自InputStream类
4.2.1 FileInputStream构造方法和常用方法
4.2.1.1构造方法
- FileInputStream(File file); 通过打开一个到实际文件的连接来创建一个
FileInputStream
,该文件通过文件系统中的File
对象file
指定。 - FileInputStream(String name); 通过打开一个到实际文件的连接来创建一个
FileInputStream
,该文件通过文件系统中的路径名name
指定。
4.2.1.2 常用方法
read() 方法,读取输入流。读取输入流的下一个字节,返回一个0-255之间的int类型整数。如果到达流的末端,返回-1。
is = new FileInputStream("test.txt"); int i; while ((i = is.read()) != -1) { System.out.println("out: " + (char)i); }
read(byte[] b) 方法,读取输入流。读取多个字节,存入字节数组b,返回实际读入的字节数。
InputStream is = null; byte[] buffer = new byte[4];//每次读取4个字节try { is = new FileInputStream("test.txt"); is.read(buffer); System.out.println("available: " + is.available());//观察在读取的过程中,available 值。 for (byte b : buffer) { System.out.println((char)b); }}...
read (byte[] b, int off, int len); 方法,读取输入流。每次读取len个字节,存入字节数组b,从off下标开始存储。
~~~java
File file = new File("helloworld.txt");try(InputStream is = new FileInputStream(file);){ byte[] b = new byte[10]; while (true) { int read = is.read(b, 0, 10); // 当每次读取的个数刚好是 byte[] 的长度,则可以这么简写: // int read = is.read(b); if (read == -1) { break; } String string = new String(b, 0, read); System.out.print(string); }} catch (FileNotFoundException e) { e.printStackTrace();} catch (IOException e) { e.printStackTrace();}
~~~
close() 方法,关闭当前流,释放与该流相关的资源,防止资源泄露。在带资源的try语句中将被自动调用。关闭流之后还试图读取字节,会出现IOException异常。
skip(long n) 方法,跳过(放弃)当前流的n个字节,返回实际跳过的字节数。(了解)
5. 字节输出流:
5.1 OutputStream类的常用方法
- write (int b); 将指定的字节写入此输出流。
- write(byte[] byte); 将
b.length
个字节从指定的 byte 数组写入此输出流。 - write(byte[] byte, int off, int len); 将指定 byte 数组中从偏移量
off
开始的len
个字节写入此输出流。 - flush(); 用于清空缓存里的数据,并通知底层去进行实际的写操作。(强制把缓存区里面的数据写入到文件)
- close();关闭当前流,释放与该流相关的资源。
5.2 OuputStream类的子类:文件输出类FileOutputStream
提供了文件的基本写入能力,继承自 OuputStream类
注意:
- 如果进行写操作的文件不存在,则自动创建该文件。
- 如果文件所在的路径也不存在则报错。
5.2.1 FileOutputStream构造方法和常用方法
课堂练习一:String content = “拉萨扩大解放了as建立地方看见拉萨的肌肤绿卡时间的分绿卡时间的分利咔”;
写一个方法,接收一个字符串。将该字符串写入到File(路径自己指定)中。返回boolean
课堂练习二:编写一个方法,接受第一个FIle fromFile,接受第二参数 File toFile;
将 fromFIle 文件内容复制到 toFile 中。
一边读,一边写
5.2.1.1 构造方法
- public FileOutputStream(String name); 通过打开一个到实际文件的连接来创建一个
FileOutputStream
,该文件通过文件系统中的路径名name
指定。 - public FileOutputStream(String name,boolean append);通过打开一个到实际文件的连接来创建一个
FileOutputStream
,该文件通过文件系统中的路径名name
指定。如果第二个参数为true,则将字节写入文件末尾处,而不是写入文件开始处。 - public FileOutputStream(File file):通过打开一个到实际文件的连接来创建一个
FileOutputStream
,该文件通过文件系统中的File
对象file
指定。 - public FileOutputStream(File file,boolean append);通过打开一个到实际文件的连接来创建一个
FileOutputStream
,该文件通过文件系统中的File
对象file
指定。如果第二个参数为true,则将字节写入文件末尾处,而不是写入文件开始处。
5.2.1.1 常用方法
write (int b); 将指定的字节写入此输出流。
try {File file = new File("test.txt");OutputStream fos = new FileOutputStream(file);byte b = 'a';fos.write(b);fos.flush();fos.close();}...
结果:
write(byte[] byte); 将
b.length
个字节从指定的 byte 数组写入此输出流。try {File file = new File("test.txt");OutputStream fos = new FileOutputStream(file);byte b[]= "abcdefg".getBytes();fos.write(b);fos.flush();fos.close();}...
结果:
write(byte[] byte, int off, int len); 将指定 byte 数组中从偏移量
off
开始的len
个字节写入此输出流。try {File file = new File("test.txt");OutputStream fos = new FileOutputStream(file);byte b[]= "abcdefg".getBytes();fos.write(b,1,3);fos.flush();fos.close();}...
结果:
flush(); 用于清空缓存里的数据,并通知底层去进行实际的写操作。(强制把缓存区里面的数据写入到文件)
close();关闭当前流,释放与该流相关的资源。
6 字节缓冲流
BufferedInputStream与BufferedOutputStream分别是FilterInputStream类和FilterOutputStream类的子类,实现了装饰设计模式。提高了读写性能。
6.1字节输入缓冲流 BufferedInputStream
BufferedInputStream是带缓冲区的输入流,默认缓冲区大小是8Kb,能够减少访问磁盘的次数,提高文件读取性能;
使用方式:
try { File file = new File("test.txt"); InputStream fos = new FileInputStream(file); BufferedInputStream bis = new BufferedInputStream(fos,2*1024);//2*1024设置需要的缓冲区大小 byte b[] =new byte[1024]; while (bis.read(b)!=-1) { for (byte c : b) { System.out.println((char)c); } } bis.close();}
6.2 字节输出缓冲流 BufferedOutputStream
BufferedOutputStream是带缓冲区的输出流,能够提高文件的写入效率。
使用方式:
try { File file = new File("test.txt"); OutputStream fos = new FileOutputStream(file); BufferedOutputStream bos =new BufferedOutputStream(fos,2*1024);//2*1024设置需要的缓冲区大小 byte b = "a"; bos.write(b); bos.flush();//带有缓冲区,所以必须刷新。 bos.close();}...
6.3 字节缓冲输入流特有的方法(了解)
(了解)mark(int readlimit) 方法(只有BufferedInputStream才支持),在流的当前位置做个标记,参数readLimit指定这个标记的“有效期”,如果从标记处开始往后,已经获取或者跳过了readLimit个字节,那么这个标记失效,不允许再重新回到这个位置(通过reset方法)。也就是你想回头不能走得太远呀,浪子回头不一定是岸了,跳过(获取)了太多字节,标记就不再等你啦。多次调用这个方法,前面的标记会被覆盖。
如果我们在 M 处做标记,readLimit为绿色部分,当流的指针在 A 处的时候,这个标记依然有效,可是一旦指针跑到 B 处,标记就失效了。
(了解)reset() 方法(只有BufferedInputStream才支持),用于重定位到最近的标记。如果在这之前mark方法从来没被调用,或者标记已经无效,会抛出IOException。如果没有抛出这个异常,将当前位置重新定位到最近的标记位置。
InputStream is = null; try { is = new BufferedInputStream(new FileInputStream("test.txt")); is.mark(4); is.skip(2); is.reset(); System.out.println((char)is.read()); } finally { if (is != null) { is.close(); } }}
课后练习
- 写一个方法,接收一个参数String text,接受第二个参数File saveFile。将text字符串内容写入到saveFile中。返回boolean
public class SaveFile { public static boolean Read(String text, File saveFile) { if (text == null || "".equals(text) || saveFile == null) { return false; } byte[] bytes = text.getBytes(); // File file = new File("saveFile"); try (FileOutputStream fileOutputStream = new FileOutputStream(saveFile);) { fileOutputStream.write(bytes, 0, text.length()); return false; } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return false; } public static void main(String[] args) { boolean read = Read("abcdefg", new File("a.txt")); System.out.println(read); }
2 编写一个方法,接受第一个参数FIle fromFile,接受第二参数 File toFile;将 fromFIle 文件内容复制到 toFile 中。
public class Main { public static void copyFile(File formFile, File toFile) { if (formFile.exists()) { try (FileInputStream fileInputStream = new FileInputStream(formFile); FileOutputStream fileOutputStream = new FileOutputStream(toFile);) { byte[] b = new byte[1024];//以这个大小来读取 while (true) { int read = fileInputStream.read(b);// fileInputStream.read(b,0,b.length); if (read == -1) { return; } fileOutputStream.write(b,0, read);//指定数组b 从0开始到read的长度 } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args) { copyFile(new File("a.txt"), new File("c.txt")); }
3.从键盘输入一个关键字,在 D:盘查找文件,如果文件名中包含该关键字,则输出这个文件的绝对路径,如果都没有找到,则输出找不到相关信息。
public class Find { public static int findFile(File file,String keyName) { int i=0; File[] listFiles = file.listFiles();// String[] str = file.list(); if (listFiles.length == 0 || listFiles == null) { return -1 ; } for (File f : listFiles) { if (f.isDirectory()) { try { int findFile = findFile(f,keyName); i+=findFile; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } if (f.getName().contains(keyName)) {// System.out.println(f.getName()); System.out.println(f.getAbsolutePath()); } } return i; } public static void main(String[] args) { File file = new File("D:"); Scanner scanner = new Scanner(System.in); System.out.println("请输入关键字"); String keyName = scanner.next(); int findFile = findFile(file,keyName); if (findFile<=0) { System.out.println("找不到"); } }
4.将JAVA LOGO 图片 通过鼠标右键保存到 D盘(D:\cat.jpg)中,然后使用java程序 实现:
- 剪切该图片到E盘(E:\cat.jpg)中。
再从E盘把该图片的 “一半” 复制一份到D盘中。
File file1 = new File("Letter/1.jpg"); File file2 = new File("Love/1.jpg"); try (FileInputStream fis = new FileInputStream(file2); FileOutputStream fos = new FileOutputStream(file1);) { byte[] b = new byte[1024]; int a = 0; while (true) { int read = fis.read(b); if (read == -1) { return; } fos.write(b, 0, read); a += read; if (a >= file2.length() / 2) {// 只复制一半 break; } } System.out.println("复制结束"); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }
在D盘指定一个目录(要求目录下面有子目录和文件(图片,文档等),子目录里面也放一些目录和文件,以此类推,可以多放几层)。然后,复制该D盘该目录下所有文件(含目录)到 E盘指定目录下 。
即:将一个目录内的所有文件(含目录) 全部复制到 另一个目录下!
public class copyAll { public static void copyDirectory(File srcDir,File destDir) { File[] listFiles = srcDir.listFiles(); if (listFiles==null) { return; } for (File file : listFiles) { File srcFile = file; File destFile = new File(destDir, file.getName());//得到目标文件的路径描述 if (file.isDirectory()) { System.out.println("正在创建目录:" + destFile); destFile.mkdir();// 在 destDir 创建对应的目标目录 copyDirectory(srcFile, destFile);//递归,得到里面的文件 }else { //复制文件 System.out.println("正在copy文件:从" + srcFile + "到" + destFile); Main.copyFile(srcDir, destDir);//复制 } } } public static void main(String[] args) { File srcDir = new File(""); File destDir = new File(""); copyDirectory(srcDir, destDir); }
- Java I/O流复习(一)—File类、字节流、字节缓冲流
- Java I/O流复习(二)—字符流、字符缓冲流、以及和字节流的区别
- Java-I/O操作之File类、字节流
- I/O流中字节流与字节缓冲流
- Java I/O(一)字节流与字符流
- I/O字节流
- Java I/O(一)--字节流,字符流
- 【Java.IO】I/O 【字节/字符】【处理流】 - 之 - 【缓冲流 】- Buffered*
- java(I/O流 三---字节流)
- JAVA I / O操作与字节流
- java编程 I/O编程--字节流
- Java I/O 字节流 文件复制
- Java之字节流、字节缓冲流
- I/O中字节流
- I/O之字节流
- I/O--3(字节流)
- 文件 I/O字节流
- Java-Java I/O流解读之基于字节的I / O和字节流
- 第三篇:设计模式六大原则: 一个萝卜一个坑 -- 单一职责原则
- C++11:线程
- Tomcat的使用(详细流程)
- [LintCode]8.旋转字符串
- 2017中国大学生程序设计竞赛
- Java I/O流复习(一)—File类、字节流、字节缓冲流
- NXP LPC54110试用体验2:在keil中使用J-LINK烧录环境搭建篇
- 摄影口诀--针对不同情景
- pywin32不能安装如何解决
- 一步步写STM32 OS【三】PendSV与堆栈操作
- 跳动的心
- 第四篇:设计模式六大原则: 一国两制 -- 开放封闭原则
- C++学习之路(8)---Qt学习—qt共享内存的使用
- Shaolin