package io;
import java.io.File;
//三种写法相同
public class OpenFile {
public static void main(String[] args) {
File f = new File("a.txt");//相对路径(当前文件夹下)
File f1 = new File("E:\\IO\\a.txt");//绝对路径
File f2 = new File("E:\\IO", "a.txt");//(目录, 路径), 便于在相同目录下操作不同文件(路径固定, 文件变量)
//跨平台文件路径分隔符File.separator
File f3 = new File("E:"+File.separator+"IO"+File.separator+"a.txt");
}
}
注意:以下方法若无特殊说明,则对文件以及文件夹均有效。
方法 (访问文件名) | 意义 |
---|---|
getName() | 获取File名称 |
getPath() | 获取File路径 |
getAbsoluteFile() | 获取用当前文件或文件夹的绝对路径构成的File对象 |
getAbsolutePath() | 获取File的绝对路径 |
getParent() | 获取上级目录名称 |
renameTo(File f) | 修改File为新File f |
方法 (文件检测) | 意义 |
---|---|
exists() | 判断File是否存在 |
canRead() | 判断File是否可读 |
canWrite() | 判断File是否可写 |
isFile() | 判断当前File是否是文件, 使用前必须保证文件存在 |
isDirectory() | 判断当前File是否是目录,使用前必须保证目录存在 |
方法 (获取常规文件信息) | 意义 |
---|---|
lastModify() | 获取文件最后一次修改时间 |
length() | 获取File长度 |
方法 (文件相关操作) | 意义 |
---|---|
createNewFile() | 新建文件 (仅可用于文件) |
delete() | 删除文件 (若文件夹为空,也可以使用delete删除,若非空则删除失败) |
方法 (目录相关操作) | 意义 (仅可用于文件夹) |
---|---|
mkdir() | 创建单级目录,一次只能创建一个文件夹 |
mkdirs() | 创建多级目录 |
list() | 返回当前目录所包含文件以及子目录的String对象 |
listFiles() | 返回当前目录所包含的文件以及子目录的File对象 |
package io;
import java.io.File;
import java.io.IOException;
public class OpenFile {
public static void main(String[] args) {
/**
* 访问文件名(文件和文件夹)
*/
File f1 = new File("E:\\IO\\1.txt");//打开文件
File m1 = new File("E:\\IO\\test");//打开文件夹
System.out.println(f1.getName());//1.txt
System.out.println(f1.getPath());//E:\IO\1.txt
File f2 = f1.getAbsoluteFile();//获得一个用当前文件的绝对路径构成的File对象
System.out.println(f1.getAbsolutePath());//E:\IO\1.txt
System.out.println(f1.getParent());//E:\IO
//文件或文件夹重命名,参数是File类型文件,文件的路径要与源文件路径一致
f1.renameTo(new File("E:\\IO\\1_rename.txt"));//E:\\IO\\1.txt => E:\\IO\\1_rename.txt
m1.renameTo(new File("E:\\IO\\test_rename"));//E:\\IO\\test => E:\\IO\\test_rename
/**
* 文件检测(文件和文件夹)
*/
System.out.println(f1.exists());//false,被改名为1_rename.txt
File f3 = new File("E:\\IO\\2.txt");
File m2 = new File("E:\\IO\\test2");
System.out.println(m2.exists());//该文件夹存在
System.out.println(f3.canRead());//true
System.out.println(f3.canWrite());//true
System.out.println(m2.canRead());//false,目录不可读写
System.out.println(m2.canWrite());//false,目录不可读写
System.out.println(f3.isFile());//true
System.out.println(m2.isDirectory());//true
/**
* 获取常规文件信息
*/
System.out.println(f3.lastModified());//1587045172334,获取最后一次修改时间
System.out.println(f3.length());//2.txt内容为“abc”,每个英文字符占1bit,长度为3bit,每个汉字占3bit
/**
* 文件相关操作
*/
File f4 = new File("E:\\IO\\3.txt");
//先判断要创建的文件是否存在,若不存在,再创建,若存在,则不会创建
if(f4.exists() == false) {//if(!f4.exists()){...}
try {
f4.createNewFile();//只能用来新建文件,不能新建文件夹,文件夹用mkDir()
} catch (Exception e) {
e.printStackTrace();
}
}//E:\\IO\\3.txt被创建
f4.delete();//new File("E:\\IO\\3.txt").delete();删除文件
new File("E:\\IO\\test2\\b\\c").delete();//删除文件夹
/**
* 目录相关操作
* mkDir()创建单级目录,mkDirs()创建多级目录
* list()返回当前文件夹的下级文件以及文件夹,listFile返回当前文件夹的下级文件以及文件夹的File对象
*/
//只能创建文件夹,就算写E:\\IO\\test2\\c\\d\\1.txt也只是新建一个叫做1.txt的文件夹
//在E:\\IO\\test2下新建文件夹b,在b下新建文件夹c
//方法一:mkdir()单级创建,每次只能新建一个文件夹
File f5 = new File("E:\\IO\\test2\\b");
f5.mkdir();
File f6 = new File("E:\\IO\\test2\\b\\c");
f6.mkdir();
//在E:\\IO\\test2下新建文件夹c,在a下新建文件夹d
//方法二:mkdirs()多级创建
File f7 = new File("E:\\IO\\test2\\c\\d");
f7.mkdirs();
String[] str = m2.list();
for(String s : str) {
System.out.println(s);
}//不包括子文件夹的子文件夹,不包括子文件夹的子文件夹的文件
File[] file = m2.listFiles();
for(File f : file) {
System.out.println(f);
}//不包括子文件夹的子文件夹,不包括子文件夹的子文件夹的文件
//getPath()与getAbsolutePath()所判断的文件可以不存在
//但若文件不存在, getParent()返回null
//String[] list()返回指定目录下的所有文件和文件夹, 包含隐藏文件和文件夹, 目录必须存在
}
}
package io;
import java.io.File;
/**
* 递归遍历文件
* 判断当前读取的是文件还是文件夹,如果是文件则输出文件的路径,
* 如果是文件夹,则读取其内部文件,对其内部文件以及文件夹的操作与之前相同
* @author MCC
*
*/
public class RTFile {
public static void main(String[] args) {
File file = new File("E:\\IO");
RTFile.rtfile(file);
}
//递归遍历
public static void rtfile(File f) {
if(f.isFile() == true) {
System.out.println("文件:" + f.getName() + "\t路径:" + f.getAbsolutePath());
}else {
// System.out.println("文件夹:" + f.getName() + "\t路径:" + f.getAbsolutePath());
File[] file = f.listFiles();
for(File ff : file) {
// if(ff != null && ff.length() > 0) { //如果想遍历内容不为空的文件,则加上这句话
rtfile(ff);
// }
}
}
}
}
package io.file;
import java.io.*;
import java.util.*;
/**
* 筛选指定名称的文件, 为了演示方便, 本例中筛选java文件
* @author 14251
*
*/
public class FileNameFilterDemo {
public static File[] getFile(String dir, String str) {//传入要查找的目录和什么类型的文件
File file = new File(dir);
Set<File> set = new HashSet<File>();
if(!file.exists()) {
throw new RuntimeException("File is not exist!");
}
if(!file.isDirectory()) {
throw new RuntimeException("File is not a file!");
}else {
//listFiles()返回当前目录下的所有文件和文件夹的File对象, list()返回String
File[] fileArray = file.listFiles();
// for(int x=0; x
for(File f : fileArray) {
String name = f.getName();
if(name.endsWith(".java")) {
set.add(f);
}
}
return set.toArray(new File[set.size()]);
}
}
//主函数
public static void main(String[] args) {
File[] f = getFile("E:\\IO", ".java");
for(File ff : f) {
System.out.println(ff.getName()+": "+ff.length());
}
}
}
package io.file;
import java.io.*;
/**
* 递归删除由内容的目录
* @author 14251
*
*/
public class DeleteDirDemo {
public static boolean deleteFiles(String dir) {
boolean flag = false;//判断是否删除成功, 内部文件夹都删除成功了, 最外层文件夹才能删除成功
File fdir = new File(dir);
if(!fdir.exists()) {
throw new RuntimeException("Directory is not exist!");
}
if(!fdir.isDirectory()) {
throw new RuntimeException("It is not a directory!");
}else {
File[] file = fdir.listFiles();
for(File f : file) {
if(f.isDirectory()) {
deleteFiles(f.getAbsolutePath());
}else {
f.delete();//文件一定能删除成功
}
}
flag = fdir.delete();//文件夹只有在不包含文件时才能被删除, 只需要判断文件夹是否删除成功即可
}
return flag;
}
//主函数
public static void main(String[] args) {
System.out.println(deleteFiles("E:\\11111"));
}
}
package io.file;
import java.io.*;
import java.util.*;
/**
* 获取指定目录下指定后缀名文件的绝对路径, 并将其保存在一个文件中
* @author 14251
* 思路:
* 1. 对指定目录进行递归, 获取全部符合要求的文件
* 2. 将文件的绝对路径保存在集合中
* 3. 将集合数据写入到文件中
*/
public class GetAbsouluteDemo {
public static void getFileDoc(String dir, String target, String doc) throws IOException{
//传入目录, 指定文件的后缀名, 要写入的文本路径
List<String> list = new ArrayList<String>();
File directory = new File(dir);
//判断目录是否存在
if(!directory.exists()) {
throw new RuntimeException("Directory is not exist!");
}
if(!directory.isDirectory()) {
throw new RuntimeException("It is not a file!");
}else {
//递归遍历文件, 获取符合要求的文件, 并写入集合中
File[] file = directory.listFiles();
for(File f : file) {
if(f.isDirectory()) {
getFileDoc(f.getAbsolutePath(), target, doc);
}else {
if(f.getName().endsWith(target)) {
list.add(f.getAbsolutePath());
}
}
}
}
//将集合内的数据写入到外部文本中
//输出流
BufferedWriter br = new BufferedWriter(new FileWriter(doc));
//遍历集合取出元素
for(String s : list) {
br.write(s);
br.newLine();
br.flush();
}
br.close();
}
//主函数
public static void main(String[] args) {
try {
getFileDoc("E:\\IO", ".java", "E:\\IO\\java.txt");
} catch (IOException e) {
e.printStackTrace();
}
}
}
1. 概念:
iO流用来处理设备之间-的数据传输。
Java程序中,对于数据的输入/输出操作以"流(stream)" 的方式进行。
java.io包下提供了各种"流"类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据。
2. 输入输出:
输入input:读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中。
输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中。
抽象基类 | 字节流 | 字符流 |
---|---|---|
输入流 | InputStream | Reader |
输出流 | OutputStream | Writer |
Java的IO流共涉及40多个类,实际上都是从上面4个抽象基类派生的。由这四个类派生出来的子类名称都是以其父类名作为后缀的。
分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
---|---|---|---|---|
抽象基类 | InputSteam | OutputStream | Reader | Writer |
访问文件 | FileInputSteam | FileOutputStream | FlieReader | FileWriter |
访问数组 | ByteArrayInputSteam | ByteArrayOutputStream | CharArrayReader | CharArrayWriter |
访问管道 | PipedInputSteam | PipedOutputStream | PipedReader | PipedWriter |
访问字符串 | StringReader | StringWriter | ||
缓冲流 | BufferedInputSteam | BufferedOutputStream | BufferedReader | BufferedWriter |
转换流 | InputSteamReader | OutputStreamWriter | ||
对象流 | ObjectInputSteam | ObjectOutputStream | ||
FilterInputSteam | FilterOutputStream | FilterReader | FilterWriter | |
打印流 | PrintStream | PrintWriter | ||
推回输入流 | PushbackInputSteam | PushbackReader | ||
特殊流 | DataInputSteam | DataOutputStream |
注意:
package io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
/**
* 操作文件用File类
* 操作文件内容用输入输出流
* @author MCC
*
*/
public class TestFileInputStream {
public static void main(String[] args) {
FileInputStream fis = null;
try {
/**
* 读取文件内容
*/
// FileInputStream file = new FileInputStream(new File("E:\\IO\\test2\\xixi.txt"));
fis = new FileInputStream("E:\\IO\\test2\\xixi.txt");
byte[] b = new byte[1024];
int len = 0;
while((len=fis.read(b))!=-1){
System.out.println(new String(b));
}
fis.close();//流使用完毕之后一定要关闭
} catch (Exception e) {
e.printStackTrace();
} finally{
try{
if(fis!=null){
fis.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
}
}
注意1:
注意2:
writer()方法会覆盖已有文件,具体情况如下:
package io;
import java.io.FileOutputStream;
public class TestFileOutputStream {
public static void main(String[] args) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream("E:\\IO\\test2\\lala.txt");
String str = "efg";
fos.write(str.getBytes());//需要byte类型数据,不是引类型,需要调用getXxx()方法转换
fos.flush();
} catch (Exception e) {
e.printStackTrace();
}
finally{
try{
if(fos!=null){
fos.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
}
}
package io;
import java.io.*;
public class AvailiableDemo {
public static void main(String[] args) {
//字节输入流的available()方法
try {
FileInputStream fis = new FileInputStream("E:\\IO\\test.txt");//test_append
int num = fis.available();
System.out.println(num);//11
byte[] b = new byte[fis.available()];//创建一个刚刚好的数组
fis.read(b);
System.out.println(new String(b));//test_append
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
编写一个程序,把一个文件(或图片、音视频等)复制的到指定文件夹下。
package io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
* 编写一个程序,把一个文件复制的到指定文件夹下
* 1.将E:\IO\test2\xixi.txt复制到E:\IO\test2\a\b下;
* 2.将E:\IO\QQ截图20200417144142.png复制到E:\IO\test2\b下。
* @author MCC
*
*/
public class CopyFile {
public static void copyFile(String sourcepath, String targetpath) {
FileInputStream infile = null;
FileOutputStream outfile = null;
try {
//f用于判断文件长度,方便设置byte[]长度
File f = new File(sourcepath);
infile = new FileInputStream(f);
outfile = new FileOutputStream(targetpath);
//设置数组长度
byte[] fbyte = new byte[1024];
//读文件内容到数组
int len = 0;
while((len=infile.read(fbyte))!=-1){
//写文件到目标路径
outfile.write(fbyte, 0, len);
}
//刷新文件
outfile.flush();
//关闭流
outfile.close();
infile.close();
} catch (Exception e) {
e.printStackTrace();
} finally{
try{
if(outfile!=null){
outfile.close();
}catch(Exception e){
e.printStackTrace();
}
try{
if(infile!=null){
infile.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
public static void main(String[] args) {
CopyFile.copyFile("E:\\IO\\test2\\xixi.txt", "E:\\IO\\test2\\a\\b\\xixi_copy.txt");
CopyFile.copyFile("E:\\IO\\QQ截图20200417144142.png", "E:\\IO\\test2\\b\\QQ截图20200417144142_copy.png");
}
}
注意:字符流只适用于文件内容是字符的文件。
读取文件操作步骤:
1.建立一个流对象,将已存在的一个文件加载进流。
FileReader fr = new FileReader(“File对象或文件路径”);
2.创建一个临时存放数据的数组。
char[ ] ch = new char[1024];
3.调用流对象的读取方法将流中的数据读入到数组中。
fr.read(ch);
4.关闭流资源。
fr.close();
package io;
import java.io.FileReader;
public class TestFileReader {
public static void main(String[] args) {
FileReader fr = null;
try {
fr = new FileReader("E:\\IO\\3.txt");
char[] ch = new char[1024];
fr.read(ch);
System.out.println(ch);//123abc
} catch (Exception e) {
e.printStackTrace();
} finally{
try{
if(fr!=null){
fr.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
}
}
写入文件操作步骤:
1.创建流对象,建立数据存放文件。
FileWriter fw = new FileWriter(“File对象或文件路径”);
2.调用流对象的写入方法,将数据写入流。
fw.write(“text”);
3.输出流关闭之前需要清空缓存。
fw.flush();
4.关闭流资源,并将流中的数据清空到文件中。
fw.close();
package io;
import java.io.FileWriter;
public class TestFileWriter {
public static void main(String[] args) {
FileWriter fw = null;
try {
fw = new FileWriter("E:\\IO\\4_writer.txt");
String str = "write 123";
fw.write(str);
fw.flush();
} catch (Exception e) {
e.printStackTrace();
} finally{
try{
if(fw!=null){
fw.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
}
}
编写一个程序,把一个文件复制的到指定文件夹下。
package io;
import java.io.*;
/**
* 演示FileReader和FileWriter
* @author 14251
*
*/
public class FileRWDemo {
public static void main(String[] args) {
FileReader fr = null;
FileWriter fw = null;
try {
//read(): 一次读一个, 返回读取到的字符的ASCII码, 读取结束返回-1
//read(char[] ch): 将读取到的字符存入ch中, 返回存入元素的个数, 读取结束返回-1
fr = new FileReader("E:\\IO\\test.txt");
fw = new FileWriter("E:\\IO\\test_copy.txt");
//第一种: 读取到数组中
char[] ch = new char[1024];
int len = 0;
while((len = fr.read(ch)) != -1) {
fw.write(ch, 0, len);
}
fw.flush();
//第二种: 单个字符读取
// int ch = 0;
// while((ch = fr.read()) != -1) {
// fw.write((char)ch);
// }
// fw.flush();
} catch (IOException e) {
throw new RuntimeException("文件不存在");
} finally {
if(fr!=null) {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fw!=null) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
定义文件路径时,注意:可以用 “/” 或者 “\”。
在写入一个文件时,如果目录下有同名文件将被覆盖。如果不想覆盖源文件可以将输出流的append参数设置为true。
在读取文件时,必须保证该文件已存在,否则出异常。
package io;
import java.io.*;
/*
* write写入后, 磁盘中的原有同名文件会被覆盖, append为true时不覆盖原有文件
*/
public class FileAppend {
public static void main(String[] args) {
//续写文件
//构造函数FileWriter(String address, boolean append);
FileWriter fw = null;
try {
fw = new FileWriter("E:\\IO\\test.txt", true);//OutputStream也可以设置为true
fw.write("_append");
fw.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(fw!=null){
fw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
注意,实质上是把输入输出流包装在缓冲流中,把数据缓冲到内存中,提高速度。
缓冲字节输入流
package io;
/**
* 缓冲字节输入流
* 读取E:\IO\2.txt文件
*/
import java.io.BufferedInputStream;
//import java.io.File;
import java.io.FileInputStream;
public class TestBufferedByteInput {
public static void main(String[] args) {
FileInputStream fs = null;
BufferedInputStream bf = null;
try {
// File f = new File("E:\\IO\\2.txt");
// FileInputStream fs = new FileInputStream(f);
// BufferedInputStream bf = new BufferedInputStream(fs);
fs = new FileInputStream("E:\\IO\\2.txt");
bf = new BufferedInputStream(fs);
byte[] b = new byte[1024];
int len = 0;
while((len=bf.read(b))!=-1){
System.out.println(new String(b));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(bf!=null){
bf.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
缓冲字节输出流
package io;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
public class TestBufferedByteOutput {
public static void main(String[] args) {
BufferedOutputStream bo = null;
try {
FileOutputStream fo = new FileOutputStream("E:\\IO\\4.txt");
bo = new BufferedOutputStream(fo);
String str = "123abc";
bo.write(str.getBytes());
bo.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(bo!=null){
bo.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
缓冲字节流实现文件复制
package io;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class BufferedByteCopy {
public static void main(String[] args) {
BufferedByteCopy.copyFile("E:\\IO\\2.txt", "E:\\IO\\test1\\2.txt");
BufferedByteCopy.copyFile("E:\\IO\\QQ截图20200417144142.png", "E:\\IO\\test1\\QQ截图20200417144142.png");
}
public static void copyFile(String source, String target) {
BufferedInputStream bf = null;
BufferedOutputStream bo = null;
try {
File f = new File(source);//打开文件,f调用length()函数
FileInputStream fs = new FileInputStream(f);//输入流
bf = new BufferedInputStream(fs);//装入输入缓冲流
FileOutputStream fo = new FileOutputStream(target);//输出流
bo = new BufferedOutputStream(fo);//装入输出缓冲流
byte[] b = new byte[1024];//定义接收数组
int len = 0;
while((len=bf.read(b))!=-1){
bo.write(b, 0, len);//写入目标文件
bo.flush();//刷新硬盘
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if(bo!=null){
try{
bo.close();
}catch(Exception e){
e.printStackTrace();
}
}
if(fo!=null){
try{
fo.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
}
}
提供了两个新方法:
类 | 方法 | 意义 |
---|---|---|
BufferedReader | readLIne() | 一次读取一行,返回String |
BufferedWriter | newLine() | 写入一个换行 |
注意:readLine()方法不返回一行末尾的回车符 '\r\n’
缓冲字节输入流
package io;
import java.io.*;
public class TestBufferedChar {
public static void main(String[] args) {
BufferedReader bf = null;
try {
FileReader fs = new FileReader("E:\\IO\\2.txt");
bf = new BufferedReader(fs);
String str = null;
while((str=bf.readLine())!=null){
System.out.println(str);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(bf!=null){
bf.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
BufferedReader的子类。
提供了两个新方法:
方法 | 意义 |
---|---|
getLineNumber() | 获取当前行号 |
setLineNumber() | 设置当前行号 |
package io;
import java.io.*;
public class LNReaderDemo {
public static void main(String[] args) {
//lineNumberReader()
try {
LineNumberReader lnr = new LineNumberReader(new FileReader("E:\\IO\\test.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\IO\\test_number.txt"));
char[] ch = new char[1024];
String str = null;
lnr.setLineNumber(10);//从第10行开始
while((str=lnr.readLine())!=null) {
bw.write(lnr.getLineNumber()+": "+str);
bw.flush();
}
bw.close();
lnr.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
package io;
import java.io.*;
/**
* 装饰类实现LineNumberReader
* @author 14251
*
*/
class MyLineNumberReader{
private Reader r;//使用Reader类的read()方法
private int number;//默认为0
MyLineNumberReader(Reader r){
this.r = r;
}
//readLine()
public String readLine() throws IOException{
StringBuilder sb = new StringBuilder();
int ch = 0;
while((ch=r.read())!=-1) {
if(ch == '\r') {
continue;
}
// if(ch == '\n') {
// return sb.toString();
// }else {
// sb.append((char)ch);
// }
if(ch == '\n') {
String res = sb.toString();
if("over".equals(res)) {
break;//结束while循环后StringBuilder中还存在字符串over
}else {
return res;
}
}else {
sb.append((char)ch);
}
}
//当存在的字符串是over时不需要返回
if(sb.length()!=0 && !"over".equals(sb.toString())) {
return sb.toString();
}
// sb.delete(0, sb.length());//可以不写, 因为每次调用readLine()方法时都会新建一个StringBuilder
return null;//break后结束循环, 内部的over不返回, 因此返回null
}
//setLineNumber()
public void setLineNumber(int num) {
this.number = num;
}
//getLineNumber()
public int getLineNumber() {
number++;
return this.number;
}
//close()
public void close() throws IOException{
r.close();
}
}
public class MyLineNumberReaderDemo {
public static void main(String[] args) {
MyLineNumberReader mnr = null;
BufferedWriter bw = null;
try {
// System.setOut(new PrintStream("C:\\Users\\14251\\Desktop\\MyLineNumberReader.txt"));
mnr = new MyLineNumberReader(new InputStreamReader(System.in));
bw = new BufferedWriter(new OutputStreamWriter(System.out));
String str = null;
while((str=mnr.readLine())!=null) {//输入over后返回null, 结束该循环
bw.write("["+mnr.getLineNumber()+"]"+str);
bw.newLine();
bw.flush();
}
}catch(Exception e) {
e.printStackTrace();
} finally {
if(mnr!=null) {
try {
mnr.close();
}catch(Exception e) {
e.printStackTrace();
}
}
if(bw!=null) {
try {
bw.close();
}catch(Exception e) {
e.printStackTrace();
}
}
}
}
}
缓冲字节输出流
package io;
import java.io.*;
public class TestBufferedChar {
public static void main(String[] args) {
FileWriter fs = null;
BufferedWriter bf = null;
try {
FileWriter fs = new FileWriter("E:\\IO\\5.txt");
bf = new BufferedWriter(fs);
bf.write("123abcdef");
bf.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(bf!=null){
bf.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
缓冲字符流实现文件复制
package io;
import java.io.*;
public class TestBufferedChar {
public static void main(String[] args) {
copyFile("E:\\IO\\2.txt", "E:\\IO\\test1\\2_BufferedWriter.txt");
}
public static void copyFile(String source, String target) {
BufferedReader bf = null;
BufferedWriter bo = null;
try {
File f = new File(source);//打开文件,f调用length()函数
FileReader fs = new FileReader(f);//输入流
bf = new BufferedReader(fs);//装入输入缓冲流
FileWriter fo = new FileWriter(target);//输出流
bo = new BufferedWriter(fo);//装入输出缓冲流
String str = null;
while((str=bf.readLine())!=null){
bo.write(str);
bo.newLine();
bo.flush();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(bf!=null){
bf.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(bo!=null){
bo.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
当想要对已有对象进行功能增强时,可以定义增强类,将已有对象作为参数传入,基于已有功能,进行功能加强,改增强类被称为装饰类,这种设计模式称为装饰设计模式。
实现方法:装饰类通过构造方法接收被装饰的对象,之后提供基于该对象的加强后的功能。
例如,FileReader有read()方法,现在想变成一次读一行,可以基于read()方法提供readLine()方法。
练习1:实现自己的readLine()
package io;
import java.io.*;
class MyBufferedReader{
private FileReader fr;
MyBufferedReader(FileReader fr){
this.fr = fr;
}
//readLine()
public String readLine() throws IOException{
//定义一个临时存储容器, 将读取到的字符存储在StringBuilder中, 最后在转换成字符串返回
StringBuilder sb = new StringBuilder();
int ch = 0;
while((ch=fr.read())!=-1) {
if(ch=='\r') {
continue;
}
if(ch=='\n') {
return sb.toString();
}else {
sb.append((char)ch);
}
}
if(sb.length()!=0){
return sb.toString();
}
return null;
}
public void close() throws IOException{
fr.close();
}
}
public class BufferedDemo {
public static void main(String[] args) {
try {
FileReader fr = new FileReader("E:\\IO\\test.txt");
MyBufferedReader mbr = new MyBufferedReader(fr);
String str = null;
while((str=mbr.readLine())!=null) {
System.out.println(str);
}
mbr.close();
}catch(Exception e) {
e.printStackTrace();
}
}
}
练习2:实现自己的装饰类
package io;
/**
* 装饰设计模式
* @author 14251
*
*/
//Person的eat方法比较单一, 只能吃饭, 现在想在吃饭的基础上添加喝水和收拾碗筷, 这就属于对eat功能的扩展
class Person {
public void eat() {
System.out.println("吃饭");
}
}
class NewPerson {
private Person p;
NewPerson(Person p){
this.p = p;
}
public void newEat() {
System.out.println("喝水");
p.eat();
System.out.println("收拾碗筷");
}
}
public class Demo1 {
public static void main(String[] args) {
Person p = new Person();
NewPerson np = new NewPerson(p);
np.newEat();
}
}
1. 概念:
2. InputStreamReader:
3. OutputStreamWriter:
4. 编码方式:
文档一般有三种编码方式:
我们一般使用UTF-8编码。
在字节流转换为字符流时,设置的编码方式要与原文件的编码方式一致,否则会出现乱码。
5. 使用场景:
6. 代码举例:
字节输入流转换为字符输入流
package io;
import java.io.FileInputStream;
import java.io.InputStreamReader;
public class TransferStream {
public static void main(String[] args) {
BufferedReader br = null;
try {
FileInputStream fs = new FileInputStream("E:\\IO\\test1\\2.txt");
// InputStreamReader isr = new InputStreamReader(fs, "UTF-8");
InputStreamReader isr = new InputStreamReader(fs);
br = new BufferedReader(isr);
String str = null;
while((str=br.readLine())!=null){
System.out.println(str);
}
} catch (Exception e) {
e.printStackTrace();
} finally{
try{
if(br!=null){
br.close();
}
}catch(EXception e){
e.printStackTrace();
}
}
}
}
字节输出流转换为字符输出流
package io;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
public class TransferStream {
public static void main(String[] args) {
BufferedWriter bw = null;
try {
FileOutputStream fo = new FileOutputStream("E:\\IO\\test1\\1.txt");
// OutputStreamWriter op = new OutputStreamWriter(fo, "UTF-8");
OutputStreamWriter op = new OutputStreamWriter(fo);
bw = new BufferedWriter(op);
op.write("123def");
op.flush();
} catch (Exception e) {
e.printStackTrace();
} finally{
try{
if(bw!=null){
bw.close();
}
}catch(EXception e){
e.printStackTrace();
}
}
}
}
练习:把控制台输入的内容写入到指定的txt文件中,当接收的是over时,就结束程序的运行。
package io;
import java.io.*;
public class SystemInDemo {
public static void main(String[] args) {
// systemIn();
mySystemIn();
}
//接收键盘输入的数据, 并转换为大写, 当输入over时结束
public static void systemIn() {
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new InputStreamReader(System.in));
// bw = new BufferedWriter(new OutputStreamWriter(System.out));//输出到控制台
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("E:\\IO\\SystemIn.txt")));//输出到指定文件
String in = null;
while((in=br.readLine()) != null) {
if("over".equals(in)) {
break;
}
bw.write(in.toUpperCase());
bw.newLine();
bw.flush();
}
} catch(Exception e) {
e.printStackTrace();
} finally {
try {
if(bw!=null) {
bw.close();
}
}catch(Exception e) {
e.printStackTrace();
}
try {
if(br!=null) {
br.close();
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
//不使用转换流的readLine()方法
public static void mySystemIn() {
BufferedInputStream bis = null;
try {
InputStream in = System.in;
bis = new BufferedInputStream(in);
StringBuilder sb = new StringBuilder();
while(true) {
int ch = bis.read();
if(ch == '\r') {
continue;
}
if(ch == '\n') {
String str = sb.toString();
if("over".equals(str)) {
break;
}
System.out.println(str.toUpperCase());
sb.delete(0, sb.length());
}else{
sb.append((char)ch);
}
}
}catch(Exception e) {
e.printStackTrace();
}finally {
try {
if(bis!=null) {
bis.close();
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
}
//键盘录入
//BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//输出
//BufferedWriter = new BufferedWriter(new OutputStreamWriter(System.out));
//详细写法
//InputStream in = System.in;
//InputStreamReader isr = new InputStreamReader(in);
//BufferedReader br = new BufferedReader(isr);
package io.practice;
import java.util.*;
import java.io.*;
/*
* 有多名学生, 每个学生有三门课的成绩, 从键盘输入数据(姓名, 性别, 成绩1, 2, 3),
* 并计算出总成绩, 将学生的信息和计算出的总成绩按照总分由高到低的顺序存储在磁盘“stuInfo.txt”中.
*/
//学生类
class Student implements Comparable<Student>{
private String name;
private String sex;
private double chinese;
private double math;
private double English;
private double sum;
Student(String name, String sex, double chinese, double math, double English){
this.name = name;
this.sex = sex;
this.chinese = chinese;
this.math = math;
this.English = English;
this.sum = chinese+math+English;
}
@Override
//double默认从小到大排序
public int compareTo(Student s) {
Double ds1 = this.sum;
Double ds2 = s.sum;
Double dc1 = this.chinese;
Double dc2 = s.chinese;
int num = ds1.compareTo(ds2);
if(num==0) {
num = dc1.compareTo(dc2);
if(num==0) {
num = this.name.compareTo(s.name);
}
}
return num;
}
@Override
public int hashCode() {
return Integer.parseInt(this.name+this.sum*23);
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof Student)) {
throw new RuntimeException("类型错误");
}else {
Student s = (Student)obj;
return this.name.equals(s.name) && this.sum==s.sum;
}
}
@Override
public String toString() {
return name+" "+sex+": "+sum+"\t"+chinese+"\t"+math+"\t"+English;
}
//getter&&setter省略
}
//录入学生信息并保存到磁盘的工具类
class StudentInfoTool{
//录入信息
//两种排序方法, 不传比较器, 升序排序, 传入比较器, 降序排序
public static Set<Student> setInfo() throws IOException{
return setInfo(null);
}
public static Set<Student> setInfo(Comparator<Student> cmp) throws IOException{
Set<Student> set = null;
if(cmp==null) {
set = new TreeSet<Student>();
}else {
set = new TreeSet<Student>(cmp);
}
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line=br.readLine())!=null){
if("over".equals(line)) {
break;
}
String[] str = line.split(",");
set.add(new Student(str[0],
str[1],
Double.parseDouble(str[2]),
Double.parseDouble(str[3]),
Double.parseDouble(str[4])));
}
br.close();
return set;
}
//学生信息存储到磁盘文件
public static void storeInfo(Set<Student> set, String address) throws IOException{
BufferedWriter bw = new BufferedWriter(new FileWriter(address));
for(Student stu : set) {
bw.write(stu.toString());
bw.flush();
bw.newLine();
}
bw.close();
}
}
//主方法
public class StudentsInfoTest {
public static void main(String[] args) {
try {
String address = "E:\\IO\\stuInfo.txt";
Comparator<Student> cmp = Collections.reverseOrder();
// Set set = StudentInfoTool.setInfo();//不传比较器
Set<Student> set = StudentInfoTool.setInfo(cmp);//传比较器
StudentInfoTool.storeInfo(set, address);
} catch (IOException e) {
e.printStackTrace();
}
}
}
package io.practice;
import java.util.*;
import java.io.*;
public class CodeDemo {
//注册信息
public static void setInfo() throws IOException{
File file = new File("E:"+File.separator+"IO"+File.separator+"code.txt");//存储和读取的位置
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//键盘录入
BufferedWriter bw = new BufferedWriter(new FileWriter(file));//写入
String info = null;
int transfer = 0;//在账号和密码之间切换
while((info=br.readLine())!=null) {
if("over".equals(info)) {
break;
}else if(transfer==0) {
bw.write(info+"=");
transfer = 1;
bw.flush();
}else {
bw.write(info);
bw.newLine();
transfer = 0;
bw.flush();
}
}
br.close();
bw.close();
}
//登录信息
public static void logIn() throws IOException{
File file = new File("E:"+File.separator+"IO"+File.separator+"code.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//使用Properties获取信息
Properties prop = new Properties();
prop.load(new FileReader(file));
//判断账号是否存在
Set<String> names = prop.stringPropertyNames();
String account = br.readLine();//第一次读取的是账号
if(!(names.contains(account))) {//账号不存在时抛出异常
throw new RuntimeException("Account is not exist!");
}else {
String password = prop.getProperty(account);//账号存在时, 获取账号对应的密码
String userIn = br.readLine();//第二次读取的是用户输入的密码, 利用了readLine()自动读取下一行的特点
if(password.equals(userIn)) {//密码正确时输出登录成功
System.out.println("Successfully log in!");
}else {//否则抛出异常
throw new RuntimeException("Password is wrong!");
}
}
br.close();
}
//主函数
public static void main(String[] args) {
try {
setInfo();
// logIn();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package io;
import java.io.IOException;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Date;
public class IOExceptionLog {
public static void main(String[] args) {
try {
int arr[] = new int[] {1, 2, 3};
System.out.println(arr[3]);
}catch(Exception e) {
try {
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String s = sdf.format(d);
PrintStream ps = new PrintStream("E:\\IO\\ExceptionLog.log");
ps.println(s);
e.printStackTrace(ps);
}catch(IOException e1) {
throw new RuntimeException("日志文件创建失败");
}
//close();
}
}
}
//自动生成日志文件log4j
package io.printStream;
import java.io.*;
/**
* PrintWriter, PrintStream读取键盘输入后输出
* @author 14251
*
*/
public class PrintStreamDemo {
public static void main(String[] args) {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//PrintWriter(OutputStream out, boolean autoFlush), 可以自动刷新
PrintWriter pw = new PrintWriter(System.out , true);
// PrintWriter pw = new PrintWriter(new FileWriter("printWriter.txt") , true);//写到文件中
// BufferedWriter bw= new BufferedWriter(pw);
String line = null;
while((line=br.readLine())!=null) {
if("over".equals(line)) {
break;
}
pw.println(line.toUpperCase());//PrintWriter有多种打印方法
}
pw.close();
br.close();
}catch(Exception e) {
e.printStackTrace();
}
}
}
SequenceInputStream是InputStream的子类,可以实现多个字节输入流的合并,例如有多个流操作多个文件,现在想将这些流操作的文件合并,就可以使用SequenceInputStream来完成。
package io.sequenceAndsplit;
import java.io.*;
import java.util.*;
/**
* 合并流:
* 假设有三个流, 分别操作三个文件, 现在想将三个文件组成一个文件
* SequenceInputStream(InputStream s1, InputStream s2)
* SequenceInputStream(Enumeration extends InputStream> e)
* @author 14251
*
*/
public class SequenceDemo {
public static void sequenceFiles(File target, File... file) throws IOException{
//输入要合并的对象, 由于可能有多个, 因此使用可变参数接收
//定义输入流与集合, 输入流读取文件, 集合存储输入流, 之后转换为Enumeration对象
List<FileInputStream> list = new ArrayList<FileInputStream>();
for(File f : file) {
list.add(new FileInputStream(f));
}
//将集合变为枚举对象
final Iterator<FileInputStream> it = list.iterator();
Enumeration<FileInputStream> en = new Enumeration<FileInputStream>() {
public boolean hasMoreElements() {
return it.hasNext();
}
public FileInputStream nextElement() {
return it.next();
}
};
//SequenceInputStream对象
SequenceInputStream sequence = new SequenceInputStream(en);
BufferedInputStream bis = new BufferedInputStream(sequence);
//输出流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(target));
byte[] b = new byte[1024];
int len = 0;
while((len=bis.read(b))!=-1) {
bos.write(b, 0, len);
bos.flush();
}
bos.close();
bis.close();
}
public static void main(String[] args) {
try {
sequenceFiles(new File("E:\\IO\\part\\merge.mp4"),
new File("E:\\IO\\part\\1.part"),
new File("E:\\IO\\part\\2.part"),
new File("E:\\IO\\part\\3.part"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
package io.sequenceAndsplit;
import java.io.*;
/**
* 将一个文件分割成(12M)分割成每4M一个文件
* @author 14251
*
*/
public class splitDemo {
public static void splitFile(File sourceFile) throws IOException{
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourceFile));
byte[] b = new byte[1024*1024*4];//每4M切割一次
int len = 0;
int count = 1;
while((len=bis.read(b))!=-1) {
BufferedOutputStream bos =
new BufferedOutputStream(new FileOutputStream("E:\\IO\\part\\"+(count++)+".part"));
bos.write(b, 0, len);
bos.flush();
bos.close();
}
bis.close();
}
//若文件较大, 例如要切割成1.5G的文件, 不能定义大小为500M的数组, 会造成内存溢出,
//可以设置一个计数器, 让流每次读取5M, 每读取一次计数器加1, 当计数器为100时, 正
//好切割出500M的碎片文件, 之后切换下一个流读取下一个500M文件
public static void splitBigFile(File sourceFile) throws IOException{
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourceFile));
BufferedOutputStream bos = null;
byte[] b = new byte[1024*1024*5];
int len = 0;
int fileName = 0;
int count = 0;//每100M加1, 用count控制写入的文件, 保证每个文件大小为500M
while((len=bis.read(b))!=-1) {
if(count%100==0) {//每500M换一个part文件
fileName++;
bos = new BufferedOutputStream(new FileOutputStream("E:\\IO\\part\\"+fileName+".part"));
}
bos.write(b, 0, len);
bos.flush();
count++;
}
bos.close();
bis.close();
}
//主函数
public static void main(String[] args) {
try {
// splitFile(new File("E:\\IO\\DJI_0185.jpg"));
// SequenceDemo.sequenceFiles(new File("E:\\IO\\part\\DD.jpg"),
// new File("E:\\IO\\part\\1.part"),
// new File("E:\\IO\\part\\2.part"),
// new File("E:\\IO\\part\\3.part"),
// new File("E:\\IO\\part\\4.part")
// );
splitBigFile(new File("E:\\面向对象方法\\第一周\\0101.mp4"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
DataInputStream和DataOutputStream是专门用来操作基本数据类型的流对象。
DataInputStream中的方法:
方法 | 方法 |
---|---|
boolean readBoolean() | byte readByte() |
char readChar() | float readFloat() |
double readDouble() | short readShort() |
long readLong() | int readInt() |
String readUTF() | void readFully(byte[] b) |
若某个类实现了 Serializable 接口,该类的对象就是可序列化的,步骤:
反序列化,步骤:
注意:如果某个类的字段不是基本数据类型或 String 类型,而是另一个引用类型,那么这个引用类型必须是可序列化的,否则拥有该类型的 Field 的类也不能序列化。
package io.serialize;
import java.io.*;
import java.util.*;
/**
* 演示对象序列化
* 将Person对象存储在本地磁盘中
* 想要序列化的对象必须实现Serializable接口
* @author 14251
*
*/
class Person implements Serializable{
private static final long serialVersionUID = -9130181056236625591L;
private String name;
private int age;
//static与transient修饰的属性不会被序列化, 但是构造函数中有这些属性, 所以在读数据时候, 读取0或null
transient String sex;
static String country = "CN";
Person(String name, int age, String sex){
this.name = name;
this.age = age;
this.sex = sex;
}
//overload toString()
public String toString() {
return name+": "+age;
}
}
public class SerializeDemo {
public static void main(String[] args) {
File file = new File("E:\\IO\\Person.txt");
// 存入
// Person p1 = new Person("LiHua", 21);
// Person p2 = new Person("XiaoMing", 22);
// try {
// writeObj(file, p1, p2);
//// writeObj(file, p1, p2, null);
// } catch (IOException e) {
// e.printStackTrace();
// }
// 读取
try {
Set<Person> set = readObj(file);
// List set = readObj("E:\\IO\\Person.txt");
for(Person p : set) {
System.out.println(p);
}
} catch (Exception e) {
e.printStackTrace();
}
}
//写数据
public static <T> void writeObj(File file, T... t) throws IOException{
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
for(Object obj : t) {
oos.writeObject(obj);
oos.flush();
}
oos.close();
}
//读数据, 方法1: 捕获EOFException, 使得程序可以读到最后
public static Set<Person> readObj(File file) throws IOException, ClassNotFoundException{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
Set<Person> set = new HashSet<Person>();
try {
while(true) {
Person p = (Person)ois.readObject();
set.add(p);
}
} catch(EOFException e) {
//不处理
} finally {
ois.close();
}
return set;
}
//读数据, 方法2: 不捕获EOFException, 通过返回null判断读到最后,
//但要在writeObject()时, 写入一个null, 并且集合要有序, 因为null必须在最后一个
public static List<Person> readObj(String str) throws IOException, ClassNotFoundException{
File file = new File(str);
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
List<Person> list = new ArrayList<Person>();
while(true) {
if(ois.readObject()==null) {
break;
}else{
list.add((Person) ois.readObject());
}
}
ois.close();
return list;
}
}
注意:Java序列化与反序列化使用的类要完全一致,类的包名、类名、类结构等统统都要相同。
如:若序列化时的Person类是其他包中的Person类,如day13.Person,则在反序列化时,接收结果的Person类要指明为day13.Person,不能省略。
PipedInputStream、PipedOutputStream、PipedReader、Pipedwriter常用于多线程中,特点是输入流与输出流可以直接相连,不需要缓冲区进行间接关联。
方法 | 意义 |
---|---|
PipedInputStream(PipedOutputStream src) | 可以相互传入对方对象,进行相互关联 |
connect(PipedOutputStream src) | 关联流 |
package io.piped;
import java.io.*;
/**
* 管道流: 用于多线程技术中
* @author 14251
*
*/
class Read implements Runnable{
private PipedInputStream pis;
Read(PipedInputStream pis){
this.pis = pis;
}
@Override
public void run() {
try {
byte[] b= new byte[1024];
int len = 0;
while((len=pis.read(b))!=-1) {
System.out.println(new String(b, 0, len));
}
pis.close();
}catch(Exception e) {
e.printStackTrace();
}
}
}
class Write implements Runnable{
private PipedOutputStream pos;
Write(PipedOutputStream pos){
this.pos = pos;
}
@Override
public void run() {
try {
pos.write("Piped Stream".getBytes());
pos.close();
}catch(Exception e) {
e.printStackTrace();
}
}
}
public class PipedDemo {
public static void main(String[] args) {
try {
PipedInputStream pis= new PipedInputStream();
PipedOutputStream pos = new PipedOutputStream();
pis.connect(pos);//将两个管道连结
Thread t1 = new Thread(new Read(pis));
Thread t2 = new Thread(new Write(pos));
t1.start();
t2.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
RandomAccessFile 类的随机访问实质上是任意访问。
package io;
/**
* 读操作
* @author MCC
*
*/
import java.io.RandomAccessFile;
public class TestRandomAccessFile {
public static void main(String[] args) {
try {
RandomAccessFile raf = new RandomAccessFile("E:\\IO\\4.txt", "r");
raf.seek(2);//从0开始,4.txt内容为123abc,第2个位置为3
byte[] b = new byte[1024];
raf.read(b);
System.out.println(new String(b));//3abc
raf.close();
}catch(Exception e) {
e.printStackTrace();
}
}
}
package io;
import java.io.RandomAccessFile;
/**
* 读写操作
* @author MCC
* RandomAccessFile不需要flush()
* seek(raf.length());可以定位到文件的最后,追加内容
* 随机写会覆盖文件内容,例如文件内容为:123456,
* 此时,seek(3);则文件内容被覆盖为:123xxx
*/
public class TestRandomAccessFile {
public static void main(String[] args) {
try {
// RandomAccessFile raf = new RandomAccessFile("E:\\IO\\4.txt", "r");
// raf.seek(2);//从0开始,4.txt内容为123abc,第2个位置为3
// byte[] b = new byte[1024];
// raf.read(b);
// System.out.println(new String(b));//3abc
// raf.close();
RandomAccessFile raf = new RandomAccessFile("E:\\IO\\5.txt", "rw");
String str = "Random Access File Write";
// raf.seek(3);
raf.seek(raf.length());//在内容的最后写,追加内容
raf.write(str.getBytes());
// raf.writeBytes(str);
raf.close();//RandomAccessFile不需要flush()
}catch(Exception e) {
e.printStackTrace();
}
}
}