文件转换成字节流,字节流为了加快速度(提供了缓冲区,一次性读多字节),再使用DataOutputStream使用固定的格式
字符有一个 readline() ,且对于中文的区别
1:如果只用FileOutputStream fileOutputStream = new FileOutputStream("d:/text.txt");
不是也能输出到"d:/text.txt"吗?为什么要用其它两个呢?能起到什么作用呢?
答案:
FileOutputStream :是字节流,它一个字节一个字节的向外边送数据
OutputStreamWriter:是字符流,它一个字符一个字符的向外边送数据
2:它们有什么区别么?
答案:
因为计算机是洋鬼子发明的,它们的英文字符占一个字节,而我们的中文是一个字符,至少占俩字节。
如果用stream,你读出来的英语再倒也罢了,读出来的中文可就是乱码或者一个个“????”。
如果你用WRITER,就不会有乱码了
3:BufferedWriter Buffer是一个缓冲区,为什么要用BUFFER呢?
答案:
如果你直接用stream或者writer,你的硬盘可能就是读一个字符或者一个字节 就去读写
硬盘一次,IO负担巨大。可是你用了Buffer,你的硬盘就是读了一堆数据之后,读写一下硬
盘。这样对你硬盘有好处。
RandomAccessFile
package classTop;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
public class RandomAccessFileTests {
private static final File file = new File("src\\testtxt\\raf.txt");
/**
* 向文件中写入内容
*/
public static void testRandomAccessFileWriter() throws IOException{
//要先将已有文件删除、避免干扰。
if(file.exists()){
file.delete();
}
RandomAccessFile rsfWriter = new RandomAccessFile(file, "rw");
//不会改变文件大小、但是他会将下一个字符的写入位置标识为10000、
//也就是说此后只要写入内容、就是从10001开始存、
rsfWriter.seek(10000);
printFileLength(rsfWriter); //result: 0
//会改变文件大小、只是把文件的size改变、
//并没有改变下一个要写入的内容的位置、
//这里注释掉是为了验证上面的seek方法的说明内容
rsfWriter.setLength(10000);
System.out.println("oo");
printFileLength(rsfWriter); //result: 0
System.out.println("xx");
//每个汉子占3个字节、写入字符串的时候会有一个记录写入字符串长度的两个字节
rsfWriter.writeUTF("享学课堂");
printFileLength(rsfWriter); //result: 10014
//每个字符占两个字节
rsfWriter.writeChar('a');
rsfWriter.writeChars("abcde");
printFileLength(rsfWriter); //result: 10026
//再从“文件指针”为5000的地方插一个长度为100、内容全是'a'的字符数组
//这里file长依然是10026、因为他是从“文件指针”为5000的地方覆盖后面
//的200个字节、下标并没有超过文件长度
rsfWriter.seek(5000);
char[] cbuf = new char[100];
for(int i=0; i<cbuf.length; i++){
cbuf[i] = 'a';
rsfWriter.writeChar(cbuf[i]);
}
printFileLength(rsfWriter); //result: 10026
//再从“文件指针”为1000的地方插入一个长度为100、内容全是a的字节数组
//这里file长依然是10026、因为他是从“文件指针”为5000的地方覆盖后面
//的200个字节、下标并没有超过文件长度
byte[] bbuf = new byte[100];
for (int i = 0; i < bbuf.length; i++) {
bbuf[i] = 1;
}
rsfWriter.seek(1000);
rsfWriter.writeBytes(new String(bbuf));
printFileLength(rsfWriter);
}
/**
* 从文件中读取内容
* 这里我们要清楚现在文件中有什么内容、而且还要清楚这些内容起始字节下标、长度
*
* @throws IOException
*/
public static void testRandomAccessFileRead() throws IOException{
/*
* 对文件中内容简单说明:
* 1、从0到1000 为空
* 2、从1001到1100是100个1
* 3、从1101到5000是空
* 4、从5001到5200是字符'a'
* 5、从5201到10000是空
* 6、从10001到10011是字符串"陈华应"
* 7、从10012到10023是"aabcde"
*/
RandomAccessFile rsfReader = new RandomAccessFile(file, "r");
//可按照自己想读取的东西所在的位置、长度来读取
rsfReader.seek(10000);
System.out.println(rsfReader.readUTF());
//读取100个字符'a'
rsfReader.seek(5000);
byte[] bbuf = new byte[200];
rsfReader.read(bbuf);
System.out.println(new String(bbuf));
//读取100个1
byte[] bbuf2 = new byte[100];
rsfReader.seek(1000);
rsfReader.read(bbuf2, 0, 100);
for(byte b : bbuf2){
System.out.print(b);
}
//读取字符'aabcde'
byte[] bbuf3 = new byte[12];
rsfReader.seek(10014);
rsfReader.read(bbuf3);
System.out.println(new String(bbuf3));
}
/**
* 打印文件长度
* @param rsfWriter 指向文件的随机文件流
* @throws IOException
*/
private static void printFileLength(RandomAccessFile rsfWriter)
throws IOException {
System.out.println("file length: " + rsfWriter.length() + " file pointer: " + rsfWriter.getFilePointer());
}
public static void main(String[] args) throws IOException {
testRandomAccessFileWriter();
testRandomAccessFileRead();
}
}
==============================================================================================
package classTop;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.time.Duration;
import java.time.Instant;
public class FileChannelTest {
public static void main(String[] args) {
File sourceFile = new File("D://alvin//IOtest//file1.mp4");
File targetFile = new File("D://file1-1.mp4");
targetFile.deleteOnExit();
try {
targetFile.createNewFile();
} catch (Exception e) {
e.printStackTrace();
}
copyFileByStream(sourceFile, targetFile);
copyFileByFileChannel(sourceFile, targetFile);
}
private static void copyFileByFileChannel(File sourceFile,File targetFile){
Instant begin = Instant.now();
RandomAccessFile randomAccessSourceFile;
RandomAccessFile randomAccessTargetFile;
try {
randomAccessSourceFile = new RandomAccessFile(sourceFile, "r");
randomAccessTargetFile = new RandomAccessFile(targetFile, "rw");
} catch (Exception e) {
e.printStackTrace();
return;
}
FileChannel sourceFileChannel = randomAccessSourceFile.getChannel();
FileChannel targetFileChannel = randomAccessTargetFile.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024*1024);
try {
while(sourceFileChannel.read(byteBuffer) != -1) {//读一串数据
byteBuffer.flip(); //回到开头
targetFileChannel.write(byteBuffer); //写
byteBuffer.clear(); //清空
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
sourceFileChannel.close();
} catch (Exception e2) {
e2.printStackTrace();
}
try {
targetFileChannel.close();
}catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("total spent: " + Duration.between(begin, Instant.now()).toMillis());
}
private static void copyFileByStream(File sourceFile,File targetFile) {
Instant begin = Instant.now();
FileInputStream fis;
FileOutputStream fos;
try {
fis = new FileInputStream(sourceFile);
fos = new FileOutputStream(targetFile);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return;
}
byte[] readed = new byte[1024*1024];
try {
while (fis.read(readed) != -1) {
fos.write(readed);
}
} catch( IOException e){
e.printStackTrace();
} finally {
try{
fos.close();
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
try {
fis.close();
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
System.out.println("total spent: " + Duration.between(begin, Instant.now()).toMillis());
}
}