1、java中的文件目录操作
File类获取文件的常用方法
public class FirstJava {
public static void main(String[] args) {
// 方法一,直接传入文件的完整路径
File file = new File("C:\\Users\\even\\Desktop\\bf");
// 方法二, 前者是父级路径,后者是目标文件名
File file1 = new File("C:\\Users\\even\\Desktop", "bf");
// 方法三:第一个参数是父级的File对象,后者是文件名
File parent = new File("C:\\Users\\even\\Desktop");
File file2 = new File(parent, "bf");
}
}
File常见的判断
public class FirstJava {
public static void main(String[] args) {
// file对象常见的判断方法
File file = new File("C:\\Users\\even\\Desktop\\bf");
// 判断是否是文件夹
file.isDirectory();
// 判断是否是文件
file.isFile();
// 判断文件是否存在
file.exists();
// 判断文件是否是隐藏
file.isHidden();
// 判断文件是否可读
file.canRead();
//判断文件是否可写
file.canWrite();
// 判断文件是否可执行
file.canExecute();
}
}
常见获取文件的信息
public class FirstJava {
public static void main(String[] args) {
// file对象常见的判断方法
File file = new File("C:\\Users\\even\\Desktop\\bf");
// 获取文件的相对路径
file.getPath();
// 获取文件的绝对路径
file.getAbsolutePath();
// 返回绝对路径的文件对象
file.getAbsoluteFile();
// 获取父级的路径
file.getParent();
// 返回父级的文件对象
file.getParentFile();
// 返回文件名称
file.getName();
}
}
常见的文件操作
public class FirstJava {
public static void main(String[] args) {
// file对象常见的判断方法
File file = new File("C:\\Users\\even\\Desktop\\bf\\abc\\a\\b\\c");
// 创建单层目录
file.mkdir();
// 创建多层目录
file.mkdirs();
// 创建文件
file.createNewFile();
// 删除文件
file.delete();
}
}
其他相关方法
public class Test {
public static void main(String[] args) {
File file = new File("yftest");
try{
System.out.println(file.isAbsolute()); //判断抽象路径是否是绝对路径
System.out.println(file.getFreeSpace());//获取磁盘的剩余空间
System.out.println(file.getTotalSpace());//返回总的磁盘空间
System.out.println(file.getUsableSpace());//返回还可使用的空间
System.out.println(file.getCanonicalFile()); //返回标签路径的文件对象
System.out.println(file.getCanonicalPath()); //返回标准版的文件路径, 不同系统的分割符不一样
System.out.println(File.separator); //返回路径的分割符
int size = new FileInputStream(file).available(); //返回文件的大小
System.out.println(size);
System.out.println(Arrays.toString(file.list())); //返回文件名的字符串数组
String[] listFiles = file.list((File dir, String name) -> true);
System.out.println(Arrays.toString(listFiles));
File[] fileLists = file.listFiles(); //获取目录下的所有文件集合
if(fileLists != null) {
for(File f: fileLists) {
System.out.println(f);
}
}
System.out.println(Arrays.toString(File.listRoots())); //获取磁盘的根目录
}catch(Exception e) {
e.printStackTrace();
}
}
}
注意:在遍历文件的时候有可能会报空指针的错误,是因为有些文件是不能访问的,有些目录是空的,这个时候就需要进行处理
2、java文件流操作
在java中需要读定文件的数据的话,需要用到流的概念;
表示从一个文件将数据返送到另一个文件,包含一个流向的问题
最终需要选择一个参照物:当前程序作为参照物;
从一个文件中读取数据到程序叫做输入流
从程序输出数据到另一个文件叫做输出流
java流的分类:按流向分类:1、输出流 =》 OutputStream和write作为基类 ; 2、输入流 =》 InputStream和Reader作为基类
按照处理数据单元划分: 1、字节流 =》字节输入流InputStream为基类;字节输出流OutputStream为基类
2、字符流 =》字符输入流Reader为基类;字符输出流Write为基类
输入流操作
public class Test {
public static void main(String[] args) {
InputStream stream = null;
try {
stream = new FileInputStream("yftest/abc.txt");
//方法一,比较耗性能,同时一次只以读取一个字符 read返回的是int可转成char
int len;
while((len = stream.read()) != -1) {
System.out.println((char)len);
}
//方法二,省性能,一次能读取指定长度的字符 推荐用法, 该方法还可以指定偏移量以及读取的长度, read返回的是读取的字符串数组的长度
// byte[] strArr = new byte[1024];
int len;
// while((len=stream.read(strArr)) != -1) {
// System.out.println(new String(strArr, 0, len));
// }
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (stream != null) stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
输出流基本操作
public class FirstJava {
public static void main(String[] args) throws IOException {
FileOutputStream handle = null;
try{
// 如果需要对文本进行追加操作,可以在第二个参数添加true
handle = new FileOutputStream("abc.txt");
handle.write("this is first file".getBytes());
// 注意: window换行 \r\n
// linux换行 \n
// mac换行 \r
handle.write("\n\r".getBytes());
handle.write("this is second file".getBytes());
handle.flush();
}catch(IOException e) {
e.printStackTrace();
}finally {
if(handle != null) handle.close();
}
}
}
注意:如果需要在末尾添加内容,那么FileOutputStream的第二个参数需要设置为true
字节缓冲流
传统方式一个字节一个字节读取或者写入数据,会频繁的发生系统内核调用(用户态-> 内核态切换)效率非常低, 所以我们可以使用字节缓冲流, 缓冲区是一个内存区域的概念, 类似于池子以块的形式写入或者读取数据,减少系统调用频率
BufferedInputStream(InputStream in): 字节缓冲输入流
BufferedOutPutStream(OutputStream out): 字节缓冲输出流
注意:字节缓冲区的大小默认是8K,即:8192字节
BufferedOutputStream的用法与FileoutPutStream比较类似
package site.ieven;
import java.io.*;
public class FirstJava {
public static void main(String[] args) throws IOException {
FileOutputStream output = new FileOutputStream("./abc.txt");
BufferedOutputStream outputStream = new BufferedOutputStream(output);
outputStream.write("this is first \n\r".getBytes());
outputStream.write("this is second".getBytes());
outputStream.close();
}
}
BufferedInputStream的用法与FileInputStream比较类似
import java.io.*;
public class FirstJava {
public static void main(String[] args) throws IOException {
FileInputStream input = new FileInputStream("./abc.txt");
BufferedInputStream inputBuffer = new BufferedInputStream(input);
byte[] bytes = new byte[1024];
int len;
while((len = inputBuffer.read(bytes)) != -1) {
System.out.println(new String(bytes, 0, len));
}
inputBuffer.close();
}
}
编码与解码
在java的io操作过程中, 存在编码与解码问题,即编码的方式需要与解码的方式需要一致,否则会出现乱码的情况
注意:一个汉字如果是GBK编码,占用2个字节的, 如果是UTF-8编码, 占用3个字节, 可以使用 "".getBytes("GBK"[默认是utf-8])来获取GBK编码的字节数
public class FirstJava {
public static void main(String[] args) throws IOException {
String str = "编程语言";
byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
System.out.println(Arrays.toString(bytes));
System.out.println(new String(bytes, "GBK")); // 这时会因为编码方式不一致导致乱码的问题
}
}
字符流
字符流是对字节流的一种包装,如果读取的文件是文本类型,优先使用字符流,可以对文件编码和解码操作
public class Test {
public static void main(String[] args) {
File file = new File("yftest/abc.txt");
FileInputStream fileInput = null;
InputStreamReader stream = null;
try {
fileInput = new FileInputStream(file);
stream = new InputStreamReader(fileInput, StandardCharsets.UTF_8);
char[] buffer = new char[1024];
while(stream.read(buffer) != -1) {
System.out.println(new String(buffer));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
//关闭流对象的时候,建议按照创建时的逆序进行创建
if(stream != null) stream.close();
if(fileInput != null) fileInput.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class Test {
public static void main(String[] args) {
File file = new File("yftest/check.txt");
FileOutputStream output = null;
OutputStreamWriter writer = null;
try {
output = new FileOutputStream(file);
writer = new OutputStreamWriter(output, StandardCharsets.UTF_8);
writer.write("有的时候做人真没有写代码这么的简单");
writer.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(writer != null) writer.close();
if(output != null) output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
输出流FileReader类的使用
public class Test {
public static void main(String[] args) {
Reader reader = null;
try {
reader = new FileReader("yftest/abc.txt");
//方法一
char[] buffer = new char[1024];
while(reader.read(buffer) != -1) {
System.out.println(new String(buffer));
}
//方法二
// int len;
// while((len = reader.read()) != -1) {
// System.out.println((char)len);
// }
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
输入流FileWriter类的用法
public class Test {
public static void main(String[] args) {
Writer writer = null;
try {
writer = new FileWriter("yftest/check.txt");
writer.write("this is test, are you ok???? hahah~~!!");
writer.flush(); //注意在写的最后添加flush;
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(writer != null) writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
注意:FileWriter如果要在末尾添加内容,那么第二个参数需要设置为true
注意:如果在处理纯文本的话,需要使用FileReader与FileWriter更为适当,如果在处理视频以及图片,那么需要用OutputStream与InputStream
BufferedReader 与 BufferedWriter的使用
public class Test {
public static void main(String[] args) {
FileReader reader = null;
BufferedReader fReader = null;
try {
reader = new FileReader("yftest/check.txt");
fReader = new BufferedReader(reader);
String str;
//读取文件的一行
while((str = fReader.readLine()) != null) {
System.out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(fReader != null) fReader.close();
if(reader != null) reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class Test {
public static void main(String[] args) {
FileWriter writer = null;
BufferedWriter bWriter = null;
try {
writer = new FileWriter("yftest/abc.txt", true);
bWriter = new BufferedWriter(writer);
bWriter.write("这个是第一行文字");
bWriter.newLine(); //表示进行换行
bWriter.write("这个是第二行文字");
bWriter.newLine();
bWriter.append("这个是第三行文字"); //表示对上一个文字的追加
bWriter.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(bWriter != null) bWriter.close();
if(writer != null) writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
ByteArrayInputStream与ByteArrayOutputStream的用法
public class Test { public static void main(String[] args) { String str = "www.baidu.com"; byte[] buffer = str.getBytes(); ByteArrayInputStream stream = new ByteArrayInputStream(buffer); int getStr; while((getStr = stream.read()) != -1) { stream.skip(3); //表示跳过指定的字节数 System.out.println((char) getStr); // System.out.println("value = " + l); } try { stream.close(); } catch (IOException e) { e.printStackTrace(); } } }
public class Test { public static void main(String[] args) { ByteArrayOutputStream stream = new ByteArrayOutputStream(); try { stream.write("this is test".getBytes()); stream.write("are you ok???".getBytes()); System.out.println(stream.toString()); } catch (IOException e) { e.printStackTrace(); }finally { try { stream.close(); } catch (IOException e) { e.printStackTrace(); } } } }
CharArrayWriter与CharArrayReader的用法
public class Test { public static void main(String[] args) { char[] chars = "今天是个好日子,明天也是好日子".toCharArray(); CharArrayReader reader = new CharArrayReader(chars); try { int len; while((len = reader.read()) != -1) { System.out.println((char)len); } } catch (IOException e) { e.printStackTrace(); } finally { reader.close(); } CharArrayWriter writer = new CharArrayWriter(); writer.write(97); writer.write(98); writer.write(99); System.out.println(writer.toString()); } }
DataInputStream与DataOutputStream的用法(注意输出的顺序与写入的顺序需要一致,否则会报错,具体看下面的例子)
public class Test { public static void main(String[] args) { FileOutputStream output = null; FileInputStream input = null; DataOutputStream stream = null; DataInputStream iStream = null; try { output = new FileOutputStream("yftest/abc.txt"); stream = new DataOutputStream(output); stream.writeBoolean(true); stream.writeByte(123); stream.writeChar('a'); stream.writeUTF("今天天气很好"); stream.writeFloat(3.1415f); stream.writeDouble(2.345); input = new FileInputStream("yftest/abc.txt"); //输出的顺序与写入的数据类型需要一致否则会报错 iStream = new DataInputStream(input); System.out.println(iStream.readBoolean()); System.out.println(iStream.readByte()); System.out.println(iStream.readChar()); System.out.println(iStream.readUTF()); System.out.println(iStream.readFloat()); System.out.println(iStream.readDouble()); } catch (IOException e) { e.printStackTrace(); } finally { try { if(stream != null) stream.close(); if(output != null) output.close(); } catch (IOException e) { e.printStackTrace(); } try { if(iStream != null) iStream.close(); if(input != null) input.close(); } catch (IOException e) { e.printStackTrace(); } } } }
ObjectInputStream 与ObjectOutputStream表示类的序列化与反序列化,用法具体参见手册
3、封装输入文字自动存入文件中的方法
public class Test { public static void main(String[] args) { FileOutputStream stream = null; OutputStreamWriter writer = null; BufferedWriter bwriter = null; InputStreamReader reader = new InputStreamReader(System.in); //对应的System.out是输出流 BufferedReader bReader = new BufferedReader(reader); try { stream = new FileOutputStream("yftest/abc.txt", true); writer = new OutputStreamWriter(stream); bwriter = new BufferedWriter(writer); String str; while(!(str = bReader.readLine()).equals("exit")) { bwriter.write(str); bwriter.newLine(); System.out.println(str); } bwriter.flush(); } catch (IOException e) { e.printStackTrace(); } finally { try { if(bwriter != null)bwriter.close(); if(writer != null) writer.close(); if(stream != null) stream.close(); bReader.close(); reader.close(); } catch (IOException e) { e.printStackTrace(); } } } }
读取网络上的静态资源
public class Test { public static void main(String[] args) { try( InputStreamReader reader = new InputStreamReader(new URL("http://www.baidu.com").openStream(), StandardCharsets.UTF_8); BufferedReader bReader = new BufferedReader(reader) ){ String cont; while((cont = bReader.readLine()) != null) { System.out.println(cont); } } catch (IOException e) { e.printStackTrace(); } } }
4、常用的方法有:
FileReader ===> FileWriter
FileInputStream ===> FileOutputStream
InputStreamReader ===> OutputStreamWriter
BufferedReader ===> BufferedWriter
5、流的另一种写法,try...catch...
public class Test { public static void main(String[] args) { try( FileReader reader = new FileReader("yftest/abc.txt"); BufferedReader bReader = new BufferedReader(reader) ){ String cont; while((cont = bReader.readLine()) != null) { System.out.println(cont); } } catch (IOException e) { e.printStackTrace(); } } }
注意:如果用以上写法就可以不用手动的关闭对应的流,系统默认会进行关闭,可以查看反编译后的代码
6、自封装一个复制文件的类
package com.yfbill.test; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.Path; public class CopyFiles { private final Path source; private final Path target; private String filters; public CopyFiles(Path source, Path target) { this.source = source; this.target = target; } public CopyFiles(Path source, Path target, String filters) { this(source, target); this.filters = filters; } /** * 获取文件 * @param file 目标文件 */ private void getFiles(File file) throws IOException { File[] files = file.listFiles(); if(files != null) { for(File val: files) { if(val.isFile()) { this.filterFiles(val); } else { this.getFiles(val); } } } } private void filterFiles(File file) throws IOException { if(this.filters != null) { int pos = file.getName().lastIndexOf("."); String ext = pos > -1? file.getName().substring(pos + 1): ""; if(ext.equals(this.filters))this.copyFiles(file); } else { this.copyFiles(file); } } private void copyFiles(File file) throws IOException { File file1 = this.target.toFile(); boolean mkdirs = true; if(!file1.exists()) { mkdirs = file1.mkdirs(); } if(mkdirs) { FileInputStream fileInputStream = new FileInputStream(file); FileOutputStream fileOutputStream = new FileOutputStream(file1.getPath() + File.separator + file.getName()); byte[] chars = new byte[1024]; while(fileInputStream.read(chars) != -1) { fileOutputStream.write(chars); } fileOutputStream.flush(); fileInputStream.close(); fileOutputStream.close(); } } public void startCopy() throws Exception { File file = this.source.toFile(); if(!file.exists()) throw new Exception("传入的源文件不是有效的源文件"); this.getFiles(file); } }