Java中的文件和流相关知识
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中的文件和流相关知识的更多相关文章
- 3,Java中的文件IO流
1,File类 ··· 概念:File对象可以表示一个文件或目录.可以对其进行增删改查. ··· 常用方法: File f = new File("."); 判断是 ...
- JAVA中接口与抛出异常的相关知识
1.接口概念:接口可以理解为一种特殊的类,由全局常量和公共的抽象方法所组成. 类是一种具体实现体,而接口定义了某一批类所需要遵守的规范,接口不关心这些类的内部数据,也不关心这些类里方法的实现细节,它只 ...
- Android(java)学习笔记167:Java中操作文件的类介绍(File + IO流)
1.File类:对硬盘上的文件和目录进行操作的类. File类是文件和目录路径名抽象表现形式 构造函数: 1) File(String pathname) Creat ...
- Android(java)学习笔记110:Java中操作文件的类介绍(File + IO流)
1.File类:对硬盘上的文件和目录进行操作的类. File类是文件和目录路径名抽象表现形式 构造函数: 1) File(String pathname) Creat ...
- Java中的文件操作
在使用计算机编程中,常常会用到对于文件的操作,以下是我对于Java中文件的相关内容学习之后的一个总结和在学习过程中遇到的一些问题. 一.什么是文件 对于文件进行操作,首先我们要知道什么是文件.在此之前 ...
- java中常量文件的配置与读取
java中常量文件的配置与读取: package com.floor.shop.user.util; import java.io.InputStream; import java.io.InputS ...
- Java中移动文件或目录的方法盘点
本文不再更新,可能存在内容过时的情况,实时更新请移步原文地址:Java中移动文件或目录的方法盘点: import org.apache.commons.io.FileUtils; import jav ...
- Java中删除文件、删除目录及目录下所有文件(转)
原文链接:Java中删除文件.删除目录及目录下所有文件 知识点:File.delete()用于删除“某个文件或者空目录”!所以要删除某个目录及其中的所有文件和子目录,要进行递归删除,具体代码示例如下: ...
- Java中读取文件
Java中读取文件,去除一些分隔符,保存在多维数组里面 public void readFile(String filePath) { File file=new File(filePath); Ar ...
随机推荐
- Understanding the difficulty of training deep feedforward neural networks
本文作者为:Xavier Glorot与Yoshua Bengio. 本文干了点什么呢? 第一步:探索了不同的激活函数对网络的影响(包括:sigmoid函数,双曲正切函数和softsign y = x ...
- e652. Getting the Font Faces for a Font Family
To create a Font object to draw text, it is necessary to specify the font face name. This example de ...
- e640. 使一个组件可拖动
This example demonstrates the code needed to make a component draggable. The object being transferre ...
- (转)SDL1.2到2.0的迁移指南
里面有些单词不好翻译所以放在开头,以备查验. BLock Image Transfer, a computer graphics operation in which two bitmap patte ...
- 关于VS2012连接MySql数据库时无法选择数据源
您的C#开发工具是用VS2012吗? No! return; 您的数据库用的是MySql吗? No! return; 您新建ADO.NET数据实体模型的时候选择数据源的时候没 ...
- [转]Git学习笔记与IntelliJ IDEA整合
Git学习笔记与IntelliJ IDEA整合 一.Git学习笔记(基于Github) 1.安装和配置Git 下载地址:http://git-scm.com/downloads Git简要使用说明:h ...
- 文件名中含有连续字符abc,相应文件中也含有字符串abc
find ./ -name '*abc*' -exec grep 'abc' {} -H \; find ./ -name '*abc*' | xargs -I '{}' grep abc {} -H ...
- win10取消开机密码
WIN10开机以后点击一下[开始]然后面它的搜索栏处输入[netplwiz]就可以看到如下图所示提示. 进入到用户长户界面,把[要使用本计算机,用户必须输入用户名和密码]前面的那个勾勾取消了,再点 ...
- 【matlab】图像直方图
使用imhist函数(要先用rgb2gray转化为灰度图像) 利用matlab计算图像直方图函数为imhist() 具体用法: imhist( i );直接显示图像i的灰度直方图: imhist(i, ...
- 关于直播学习笔记-002-Red5 & Sewise Player & Wirecast
一.工具软件 [1]. 视频采集端 Red5 Demo:http://192.168.31.107:5080/demos/simpleBroadcaster.html Telestream:Wirec ...