Java 从入门到进阶之路(二十九)
在之前的文章我们已经可以对本地对文件和目录进行新建和删除等操作,接下来我们来对文件内对具体内容进行操作。
如下代码,我们实现了一个基本的文件写入:
/**
* java.io.RandomAccessFile
* 用来读写文件数据
* RAF是基于指针进行读写的,即RAF总是在指针指向的位置读写字节,
* 并且读写后指针会自动向后移动
* RAF既可以读取文件数据也可以向文件中写入数据
*
* @author wjt
*/
public class RandomAccessFileDemo1 {
public static void main(String[] args) throws IOException {
/**
* RandomAccessFile(String path, String mode)
* RandomAccessFile(File file, String mode)
* 第二个参数为模式:常用对有 r:只读模式 rw:读写模式
*/
RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");
/**
* void write(int d)
* 写出给定的int值对应的2进制的低八位
* 00000000 00000000 00000000 00000001
*/
raf.write(1); //
System.out.println("写出完毕!");
raf.close(); }
}
在上面的代码中我们可以看出文件的读写想要到 RandomAccessFile,这里需要注意的是要抛出异常,否则编译器会报错,同时我们用到了它的一个 write() 方法来进行文件写入,接收的是一个2进制的低八位数值,假如我们写入 raf.write(97),那么就会被准化为小写字母 a。
既然能读,那就能写,接下来我们将上面写入的 1 再读取出来
/**
* 读取文件数据
*
* @author wjt
*/
public class RandomAccessFileDemo2 {
public static void main(String[] args) throws IOException {
RandomAccessFile raf = new RandomAccessFile("raf.txt", "r");
/**
* int read()
* 读取一个字节,并以10进制的int型返回
* 若返回值为-1,则表示读取到了文件的末尾
*/
int d = raf.read();
System.out.println(d); //
raf.close();
}
}
接下来我们再来看一下如何对文件进行复制
/**
* 复制文件
*
* @author wjt
*/
public class RandomAccessFileDemo3 {
public static void main(String[] args) throws IOException {
/**
* 创建一个RAF读取原文件,
* 再创建一个RAF向目标文件中写出,
* 顺序从原文件中读取每一个字节并
* 写入到目标文件中即可
*/
// 原文件,在原文件中随便写一些内容
RandomAccessFile src = new RandomAccessFile("raf.txt", "r");
// 目标文件
RandomAccessFile desc = new RandomAccessFile("raf1.txt", "rw");
// 用来保存读取到每个字节
int d = -1;
long start = System.currentTimeMillis();
while ((d = src.read()) != -1) {
desc.write(d);
}
long end = System.currentTimeMillis();
System.out.println("复制完毕!耗时:" + (end - start) + "ms"); // 复制完毕!耗时:2ms
}
}
通过上面的代码我们可以实现文件的复制,但是这样复制是比较耗时的,不如在电脑上直接复制粘贴来的快。因为这是一个从硬盘读取到内存中再写到硬盘的过程,频繁的一个字节一个字节的读取频繁地调用这个过程,所以会很慢。
如果我们不是一个字节一个字节读写,而是一组一组的读写就会提升效率,如下:
/**
* 若向提高读写效率,
* 可以通过提高每次读写的数据量来减少读写次数达到
*
* @author wjt
*/
public class RandomAccessFileDemo4 {
public static void main(String[] args) throws IOException {
RandomAccessFile src = new RandomAccessFile("raf.txt", "r");
RandomAccessFile desc = new RandomAccessFile("raf1.txt", "rw");
/**
* int read(byte[] data)
* 一次性尝试读取给定的字节数组总长度的字节量并存入到该数组中,
* 返回值为实际读取到的字节量,
* 若返回值为-1,则表示本次没有读取到任何数据(文件末尾)
*/
// 10K
byte[] buf = new byte[1024 * 10];
// 用来保存读取到每个字节
int len = -1;
long start = System.currentTimeMillis();
while ((len = src.read(buf)) != -1) {
/**
* void write(buf)
* 一次性将给定的字节数组中的所有数据写入
* void write(byte[] d, int start, int end)
* 将所给定数组中从小表start处开始的len个字节一次性写出
*/
desc.write(buf, 0, len);
}
long end = System.currentTimeMillis();
System.out.println("复制完毕!耗时:" + (end - start) + "ms"); // 复制完毕!耗时:1ms
}
}
在上面的代码中,我们定义了一个 byte 数组来每次读写 10K 的方式进行批量复制,会发现时间变短了,需要注意的是 write() 方法需要使用重载的方法,因为最后一次可能会写入多余的数组len。
我们知道 write() 方法其实写入的是数据的低八位,那我们想要写入不同的数据类型该怎么写呢?如下代码:
/**
* RAF还提供了方便读写基本类型数据的方法
*
* @author wjt
*/
public class RandomAccessFileDemo5 {
public static void main(String[] args) throws IOException {
RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");
/**
* 向文件中写入一个int最大值
* Integer.MAX_VALUE 的二进制位
* 011111111 11111111 11111111 11111111
* 文件写入为二进制的低八位,如果我们直接写入的话
* 其实写入的是低八位的 11111111,显然是错误的
* 我们可以通过位移的方式连续写四次来进行写入操作
*/
int max = Integer.MAX_VALUE; raf.write(max >>> 24); //
raf.write(max >>> 16); //
raf.write(max >>> 8); //
raf.write(max); // 11111111 // RAF 其实提供了更方便的方法来进行不同类型数据的写入
raf.writeInt(max);
raf.writeDouble(11.11);
raf.writeLong(1234L);
raf.close();
}
}
从上面的代码中我们可以通过位移的方式按顺序每次写入一个int值的八位,写四次正好是一个int值的四个字节,当然我们我们也可以用提供好的 writeInt() 方法来直接写入,其底层代码远离其实也是用到了位移的思想,如下源码:
Java 从入门到进阶之路(二十九)的更多相关文章
- Java 从入门到进阶之路(十九)
在之前的文章我们介绍了一下 Java 中的Object,本章我们来看一下 Java 中的包装类. 在 Java 中有八个基本类型:byte,short,int,long,float,double,ch ...
- Java 从入门到进阶之路(十二)
在之前的文章我们介绍了一下 Java 类的重写及与重载的区别,本章我们来看一下 Java 类的 private,static,final. 我们在之前引入 Java 类概念的时候是通过商场收银台来引入 ...
- Java 从入门到进阶之路(十八)
在之前的文章我们介绍了一下 Java 中的正则表达式,本章我们来看一下 Java 中的 Object. 在日常生活中,任何事物我们都可以看做是一个对象,在编程中是同样的道理,在 Java 编程中其实更 ...
- Java 从入门到进阶之路(十)
之前的文章我们介绍了一下 Java 中的引用型数组类型,接下来我们再来看一下 Java 中的继承. 继承的概念 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类. 继承就是子类继 ...
- Java 从入门到进阶之路(十五)
在之前的文章我们介绍了一下 Java 中的接口,本章我们来看一下 Java 中类的多态. 在日常生活中,很多意思并不是我们想要的意思,如下: 1.领导:“你这是什么意思?” 小明:“没什么意思,意思意 ...
- Java 从入门到进阶之路(十四)
在之前的文章我们介绍了一下 Java 中的抽象类和抽象方法,本章我们来看一下 Java 中的接口. 在日常生活中,我们会接触到很多类似接口的问题,比如 USB 接口,我们在电脑上插鼠标,键盘,U盘的时 ...
- Java 从入门到进阶之路(十六)
在之前的文章我们介绍了一下 Java 中类的多态,本章我们来看一下 Java 中类的内部类. 在 Java 中,内部类分为成员内部类和匿名内部类. 我们先来看一下成员内部类: 1.类中套类,外面的叫外 ...
- Java 从入门到进阶之路(二十)
在之前的文章我们介绍了一下 Java 中的包装类,本章我们来看一下 Java 中的日期操作. 在我们日常编程中,日期使我们非常常用的一个操作,比如读写日期,输出日志等,那接下来我们就看一下 Java ...
- Java 从入门到进阶之路(二十三)
在之前的文章我们介绍了一下 Java 中的 集合框架中的Collection 的迭代器 Iterator,本章我们来看一下 Java 集合框架中的Collection 的泛型. 在讲泛型之前我们先来 ...
- Java 从入门到进阶之路(二)
之前的文章我们介绍了一下用 IDEA 编辑器创建一个 Java 项目并输出 HelloWorld,本章我们来看一下 Java 中的变量和基本数据类型. 在这之前我们先来看一下 Java 中的关键字,这 ...
随机推荐
- Java实现 洛谷 P1914 小书童——密码
import java.util.Scanner; public class Main { private static Scanner cin; public static void main(St ...
- java实现识别复制串
** 识别复制串** 代码的目标:判断一个串是否为某个基本串的简单复制构成的. 例如: abcabcabc,它由"abc"复制3次构成,则程序输出:abc aa 由"a& ...
- c 到 c++
目录: 1.引用相关 2.const关键字 3.动态内存分配 1.引用相关: /* 概念:某个变量的引用等价于这个变量的别名 格式:类型名 & 引用名 = 某变量名 作用: 1. ...
- Yangcs从简书搬回来了
追求更加畅快淋漓的书写体验: 简书地址: http://www.jianshu.com/users/9913981cb400/latest_articles. Yangcs在简书[2016] 简书已经 ...
- Redis集群方式
Redis有三种集群方式:主从复制,哨兵模式和集群. 1.主从复制 主从复制原理: 从服务器连接主服务器,发送SYNC命令: 主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用 ...
- Kubernetes日志的6个最佳实践
本文转自Rancher Labs Kubernetes可以帮助管理部署在Pod中的上百个容器的生命周期.它是高度分布式的并且各个部分是动态的.一个已经实现的Kubernetes环境通常涉及带有集群和节 ...
- Azure AD(四)知识补充-服务主体
一,引言 又到了新的一周了,也到了我新的分享的时间了,还记得上一周立得Flag,其中 “保证每周输出一篇文章” ,让我特别“在意”(这里用词不太恰当).主要是我的一个大学舍友,他突然问了我一个关于写博 ...
- MATLAB实例:聚类网络连接图
MATLAB实例:聚类网络连接图 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 本文给出一个简单实例,先生成2维高斯数据,得到数据之后,用模糊C均值( ...
- 描述一下 JVM 加载 class 文 件的原理机制?
JVM 中类的装载是由 ClassLoader 和它的子类来实现的, Java ClassLoader 是一个重要的 Java 运行时系统组件.它负责在运行时查找和装入类文件的类.
- [xDebug] 服务器端的配置参数
[Xdebug] ;load xdebug extensionzend_extension_ts = path/tp/xdebug;是否开启自动跟踪xdebug.auto_trace = On;是否开 ...