1. File

  • File类可以使用文件路径字符串来创建File实例,该文件路径可以是绝对路径或相对路径
  • File类的list()方法中可以接收一个FilenameFilter参数,通过该参数可以只列出符合条件的文件
public class FileNameFilterTest {
public void main(String[] args) {
File file = new File(".");
String[] nameList = file.list(((dir, name) -> name.endsWith(".java") || new File(name).isDirectory()));
for (String name :
nameList) {
System.out.println(name);
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

2. 流(Stream)

  • Stream是从起源(source)到接收(sink)的有序数据
  • 按照流向分可以分为输入流和输出流 
    • 输入流:只能从中读取数据,不能写入数据(基类是InputStream和Reader)
    • 输出流:只能向其中写入数据,不能读取数据(基类是OutputStream和Writer)
  • 按照操作的数据单元分为字节流和字符流 
    • 字节流:操作的数据单元是8位的字节(基类是InputStream和OutputStream)
    • 字符流:操作的数据单元是16位的字节(基类时Reader和Writer)
  • 按照角色可以分为节点流和处理流 
    • 节点流:可以从/向一个特定的IO设备中读/写数据的流,也被称为低级流
    • 处理流:用于对一个已存在的流进行连接或封装来实现读/写功能,也称为高级流或包装流

3. 字节流和字符流

  • 字节流输入
    public class FileInputStreamTest {
public void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("FileInputStreamTest.java");
byte[] bytes = new byte[1024];
int hasRead = 0;
while ((hasRead = fis.read(bytes)) > 0) {
System.out.println(new String(bytes,0,hasRead));
}
fis.close();
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 字节流输出
public class FileOutputStreamTest {
public void main(String[] args) {
try (FileOutputStream fileOutputStream = new FileOutputStream("file.txt");
FileInputStream fileInputStream = new FileInputStream("FileInputStreamTest.java")) {
byte[] bytes = new byte[1024];
int hasRead = 0;
while ((hasRead = fileInputStream.read(bytes)) > 0) {
fileOutputStream.write(bytes,0,hasRead);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 字符流输入
public class FileReaderTest {
public void main(String[] args) {
try (FileReader fileReader = new FileReader("FileInputStreamTest.java")) {
char[] chars = new char[1024];
int hasRead = 0;
while ((hasRead = fileReader.read(chars)) > 0) {
System.out.println(new String(chars,0,hasRead));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 字符流输出
public class FileWriterTest {
public void main(String[] args) {
try (FileWriter fileWriter = new FileWriter("poem.txt")){
fileWriter.write("锦瑟 -李商隐\r\n");// \r\n时windows平台的换行符
fileWriter.write("锦瑟无端五十弦,一弦一柱思华年\r\n");
fileWriter.write("庄生晓梦迷蝴蝶,望帝春心托杜鹃\r\n");
fileWriter.write("沧海月明珠有泪,蓝田日暖玉生烟\r\n");
fileWriter.write("此情可待成追忆,只是当时已惘然\r\n");
} catch (IOException e) {
e.printStackTrace();
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

4. 处理流/转换流

  • 构造器参数不是一个物理节点,而是已经存在的流
  • 关闭最上层的流时,会自动关闭被该处理流包装的节点流
  • 如果进行输入/输出的是文本内容,应当考虑字符流,如果进行输入/输出的内容时二进制内容,则应该考虑使用字节流
  • 转换流用于实现将字节流转换成字符流,InputStreamReader将字节输入流转换成字符输入流;OutputStreamWriter将字节输出流转换成字符输出流
  • BufferReader流具有缓冲功能

5. 重定向标准输入/输出

  • 重定向是指改变输入/输出目标(由键盘/屏幕改为文件)
  • 重定向输出流
public class RedirectOut {
public void main(String[] args) {
try (PrintStream printStream = new PrintStream(new FileOutputStream("out.txt"))){
System.setOut(printStream);
System.out.println("普通字符串");
System.out.println(new RedirectOut());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 重定向输入流
    public class RedirectIn {
public void main(String[] args) {
try (FileInputStream fileInputStream = new FileInputStream("poem.txt")) {
System.setIn(fileInputStream);
Scanner scanner = new Scanner(System.in);
scanner.useDelimiter("\n");//只把回车作为换行符
while (scanner.hasNext()) {
System.out.println("键盘输入内容:" + scanner.next());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

6. RandomAccessFile

  • RandomAccessFile支持任意访问,可以直接调整到文件的任意地方读写数据
  • 可以向已存在的文件后追加内容
  • 只能读写文件,不能读写其他IO节点
  • 包含一个记录指针,用以标识当前读写处的位置
  • 直接将文件记录指针移动到中间某位置后进行输出会覆盖原有的内容
  • 读取文件
public class RandomAccessFileTest {
public void main(String[] args) {
try (RandomAccessFile randomAccessFile = new RandomAccessFile("poem.txt", "r")) {
System.out.println("指针初始位置:" + randomAccessFile.getFilePointer());
randomAccessFile.seek(300);
byte[] buffer = new byte[1024];
int hasRead = 0;
while ((hasRead = randomAccessFile.read(buffer)) > 0) {
System.out.println(new String(buffer, 0, hasRead));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 向文件末尾追加内容
public class AppendContent {
public void main(String[] args) {
try (RandomAccessFile randomAccessFile = new RandomAccessFile("poem.txt", "rw")) {
randomAccessFile.seek(randomAccessFile.length());
randomAccessFile.write("追加的内容!\n".getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 向指定位置添加内容
    public class InsertContent {
public void main(String[] args) throws IOException {
File file = File.createTempFile("tmp", null);
file.deleteOnExit();
try (RandomAccessFile randomAccessFile = new RandomAccessFile("poem.txt", "rw");
FileOutputStream tmpOut = new FileOutputStream(file);
FileInputStream tmpIn = new FileInputStream(file)) {
randomAccessFile.seek(300);
//将文件内容写入临时文件中
byte[] buffer = new byte[64];
int hasRead = 0;
while ((hasRead = randomAccessFile.read(buffer)) > 0) {
tmpOut.write(buffer, 0, hasRead);
}
randomAccessFile.seek(300);
randomAccessFile.write("插入的内容".getBytes());
//追加之前的内容
while ((hasRead = tmpIn.read(buffer)) > 0) {
randomAccessFile.write(buffer, 0, hasRead);
} }
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

7. 对象序列化

  • 对象序列化(Serialize)是指将一个Java对象写入IO流中
  • 对象反序列化(Deserialize)是指从IO流中恢复该Java对象
  • 序列化必须实现Serializable和Externalizable接口
  • 序列化
public class WriteObject {
public void test() {
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("object.txt"))) {
Person person = new Person("HelloWood", 22);
Person person1 = new Person("HoloWood", 33);
objectOutputStream.writeObject(person);
objectOutputStream.writeObject(person1);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 反序列化
public class ReadObject {
public void test() {
try (ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("object.txt"))) {
Person p = (Person) objectInputStream.readObject();
Person p1 = (Person) objectInputStream.readObject();
System.out.println(p.getName() + " " + p.getAge());
System.out.println(p1.getName() + " " + p1.getAge());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 反序列化时读取的仅仅时Java对象的数据,而不是Java类
  • 反序列化无须通过构造器来初始化Java对象
  • 如果序列化时写入多个对象,则反序列化时必须按实际写入顺序读取
  • 当一个可序列化类有父类时,这些父类必须时可序列化的
  • 当某个类的成员变量的类型不是基本类型或String类型而是引用类型时,这个引用类型必须也是可序列化的
  • 多次序列化同一个Java对象时,只有第一次序列化时才会把该Java对象转换成字节序列并输出
  • 当序列化某个对象后修改该对象的属性再序列化不会将修改后的属性输出
  • 当对某个对象进行序列化时,系统会自动把该对象的所有实例变量依次进行序列化
  • 如果在实例变量前用transient修饰,则该变量在实例化时会自动跳过
  • 如果重写了writeReplace()方法,则在序列化时会先调用该方法进行替换

8. NIO(New IO)

  • NIO采用内存映射的方式来处理输入输出,通过将文件或部分文件的一段区域映射到内存中进行访问
  • NIO中的所有数据都需要通过通道(Channel)传输
  • 传统IO面向流处理,NIO面向块处理
  • Buffer本质是一个数组

    • 容量(capacity):可以最大存储的数据量,不能为负值,创建后不可改变
    • 界限(limit):第一个不应该被读出或者写入的缓冲区位置索引,limit后的数据不能被读写
    • 位置(position):用于指明下一个可以被读出的或者写入的缓冲区位置索引
    • 标记(mark):标记,用于自定义记录位置
    • 0 <= mark <= position <= limit <= capacity
    • flip()方法将limit设置为position所在位置,将position置为0,为读取数据做准备
    • clear()将position置为0,limit置为capacity,但不清空数据,为再次装入数据做准备
  • Channel

    • 只能和Buffer交互
    • Channel应当通过XXXStream.getChannel()方法获取
     public class ReadFile {
public void test() {
try (FileInputStream fileInputStream = new FileInputStream("poem.txt");
FileChannel fileChannel = fileInputStream.getChannel()) {
ByteBuffer byteBuffer = ByteBuffer.allocate(256);
while (fileChannel.read(byteBuffer) != -1) {
byteBuffer.flip();
Charset charset = Charset.forName("UTF-8");
CharsetDecoder charsetDecoder = charset.newDecoder();
CharBuffer charBuffer = charsetDecoder.decode(byteBuffer);
System.out.println(charBuffer);
byteBuffer.clear();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

9. 文件锁

  • lock()锁定文件时如果无法得到文件锁,程序就会一直阻塞
  • tryLock()锁定文件时如果获得了文件锁,则会返回文件锁,否则返回null
  • tryLock(long position,long size,boolean shared) 
    • 当shared为true时,该锁是共享锁,将允许多个进程读取该文件
    • 当shared为false时,该锁时排他锁,将锁住对该文件的读写
    • 通过FileLock的release()方法释放文件锁
  • 文件锁时Java虚拟机所持有的
public class FileLockTest {
public void test() {
try (FileChannel fileChannel = new FileOutputStream("poem.txt").getChannel()){
FileLock lock = fileChannel.tryLock();
Thread.sleep(10000);
lock.release();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

10. NIO2

  • 使用FileVisitor遍历文件和目录
public class FileVisitorTest {
public void test() throws IOException {
Files.walkFileTree(Paths.get("/","home"),new SimpleFileVisitor<Path>(){
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
System.out.println("正在访问:"+file+"文件");
if (file.endsWith("poem.txt")) {
System.out.println("---已经找到目标文件---");
System.out.println("文件目录:"+file);
return FileVisitResult.TERMINATE;
}
return FileVisitResult.CONTINUE;
} @Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
System.out.println("正在访问:"+dir+"路径");
return FileVisitResult.CONTINUE;
}
});
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 使用WatchService监控文件变化
    public class WatchServiceTest {
public void test() {
WatchService watchService = null;
try {
watchService = FileSystems.getDefault().newWatchService();
Paths.get("/home/alpha/IdeaProjects/out/production/IdeaProjects/").register(watchService,
StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_MODIFY,
StandardWatchEventKinds.ENTRY_DELETE);
while (true) {
WatchKey key = watchService.take();
for (WatchEvent<?> event : key.pollEvents()) {
System.out.println(event.context() + "发生了" + event.kind() + "事件");
}
boolean valid = key.reset();
if (!valid) {
break;
}
} } catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Java中的文件和流相关知识的更多相关文章

  1. 3,Java中的文件IO流

    1,File类 ··· 概念:File对象可以表示一个文件或目录.可以对其进行增删改查. ··· 常用方法:     File f = new File(".");     判断是 ...

  2. JAVA中接口与抛出异常的相关知识

    1.接口概念:接口可以理解为一种特殊的类,由全局常量和公共的抽象方法所组成. 类是一种具体实现体,而接口定义了某一批类所需要遵守的规范,接口不关心这些类的内部数据,也不关心这些类里方法的实现细节,它只 ...

  3. Android(java)学习笔记167:Java中操作文件的类介绍(File + IO流)

    1.File类:对硬盘上的文件和目录进行操作的类.    File类是文件和目录路径名抽象表现形式  构造函数:        1) File(String pathname)       Creat ...

  4. Android(java)学习笔记110:Java中操作文件的类介绍(File + IO流)

    1.File类:对硬盘上的文件和目录进行操作的类.    File类是文件和目录路径名抽象表现形式  构造函数:        1) File(String pathname)       Creat ...

  5. Java中的文件操作

    在使用计算机编程中,常常会用到对于文件的操作,以下是我对于Java中文件的相关内容学习之后的一个总结和在学习过程中遇到的一些问题. 一.什么是文件 对于文件进行操作,首先我们要知道什么是文件.在此之前 ...

  6. java中常量文件的配置与读取

    java中常量文件的配置与读取: package com.floor.shop.user.util; import java.io.InputStream; import java.io.InputS ...

  7. Java中移动文件或目录的方法盘点

    本文不再更新,可能存在内容过时的情况,实时更新请移步原文地址:Java中移动文件或目录的方法盘点: import org.apache.commons.io.FileUtils; import jav ...

  8. Java中删除文件、删除目录及目录下所有文件(转)

    原文链接:Java中删除文件.删除目录及目录下所有文件 知识点:File.delete()用于删除“某个文件或者空目录”!所以要删除某个目录及其中的所有文件和子目录,要进行递归删除,具体代码示例如下: ...

  9. Java中读取文件

    Java中读取文件,去除一些分隔符,保存在多维数组里面 public void readFile(String filePath) { File file=new File(filePath); Ar ...

随机推荐

  1. MySQl安装全解

    这是第二次安装MySql了.第一次安装花了几个小时,理解安装的每一个页面,这次光寻找安装包就找了几个.因此感觉有必要做一次全面的安装笔记.(有点浪费时间了,可是感觉非常值得)本人系统是window7. ...

  2. 多个进程对同一个监听套接字调用函数gen_tcp:accept/1

    源于<<erlang程序设计>>的第14章的14.1.4大约第197页. 未发现多个进程对同一个监听套接字调用函数gen_tcp:accept/1比单进程的效率更高或者更快.

  3. CSS导入使用及引用的两种方法

    方法一<link rel="stylesheet" type="text/css" href="test.css"> 方法二&l ...

  4. Js注释和对象

    1.注释 单行: //注释内容 console.log('加油~');//在控制台输出一条信息: 多行: /*注释内容*/: 2.对象 1)对象是一个复合值,是根据某种引用类型创建出来的实例. 2)常 ...

  5. Sharepoint 2013 Workflow Error

    问题: (1)提示“reload the page and then start the workflow”错误 (2)提示“Unable to properly communicate with t ...

  6. Unity3D使用经验总结 编辑器扩展篇【转】

    一个引擎,最重要的就是工具,工具除了提升开发速度,提供可视化操作环境以外,还带了容错功能. 它使得大家的工作局限在一定的范围内,比如一个变量的配置,或者是一些类型的选择. 使用编辑器,使得既使不太明白 ...

  7. ChemOffice Professional 16.0新增了哪些功能

    ChemOffice Professional 16.0是为终极化学和生物组件设计,可满足化学家和生物学家的需求.ChemOffice Professional帮助科学家有效地检索数据库,包括SciF ...

  8. POJ 3093 Margaritas(Kind of wine) on the River Walk (背包方案统计)

    题目 Description One of the more popular activities in San Antonio is to enjoy margaritas in the park ...

  9. POJ 1946 Cow Cycling(抽象背包, 多阶段DP)

    Description The cow bicycling team consists of N (1 <= N <= 20) cyclists. They wish to determi ...

  10. Ubuntu12.04 Skype4.2 提示Skype can't connect,安装Skype4.3

    最近几天Skype突然不能登录啦,以为是自己密码记错啦,重置啦一下密码,发现仍然提示”Skype can't connect“,我的版本是Ubuntu12.04 Skype4.2 尝试啦很多办法仍然不 ...