文件
在C语言中,我们会定义一个FILE指针去操作文件,同样,我们在Java中也会有方法去操作文件,将文件中的数据进行操作。以下就简单介绍一下Java中的File这个类。
在使用File这个类时,肯定要创建这个类的对象,以下是创建File这个类的一些方法。
package Demo_file;
import java.io.File;
import java.io.FileInputStream;
public class Demo1_file {
/*
* File(String pathname): 根据一个路径得到File对象
* File(String parent, String child): 根据一个目录和一个子文件/目录得到File对象
* File(File parent, String child): 根据一个父File对象和一个子文件/目录得到File对象
*/
public static void main(String[] args) {
//demo1();
//demo2();
File parent = new File("D:\\学习资料");
String child = "C语言100道经典例题.docx";
File file = new File(parent, child);
System.out.println(file.exists());
System.out.println(parent.exists());
}
public static void demo2() {
String parent = "D:\\学习资料";
String child = "C语言100道经典例题.docx";
File file = new File(parent, child);
System.out.println(file.exists());
}
public static void demo1() {
File file = new File("D:\\学习资料\\C语言100道经典例题.docx");
System.out.println(file.exists());
File file2 = new File("xxx.txt");
System.out.println(file2.exists());
}
}
下面就简单介绍一下File这个类中的一些简单的方法。
package Demo_file;
import java.io.File;
import java.io.IOException;
public class Demo2_FileMethod {
/*
* 创建功能:
* public boolean createNewFile() : 创建文件 如果存在这样的文件,就不用创建了
* public boolean mkdir() : 创建文件夹 如果存在这样的文件夹,就不创建了
* public boolean mkdirs() : 创建文件夹 如果父文件不存在,会帮你创建出来
*
* 注意事项:
* 如果你创建的文件或者文件夹忘了写盘符路径,那么,默认在项目路径下
*/
public static void main(String[] args) throws IOException {
//demo1();
File dir1 = new File("aaa");
System.out.println(dir1.mkdir());
File dir2 = new File("bbb.txt"); //这样写也是可以的,文件夹也是可以有后缀的
System.out.println(dir2.mkdir());
File dir3 = new File("ccc\\ddd");
System.out.println(dir3.mkdirs()); //创建多级路径
}
public static void demo1() throws IOException {
File file = new File("yyy.txt");
System.out.println(file.createNewFile()); //如果没有就创建,返回true
File file2 = new File("zzz"); //不加后缀也是可以创建文件的,但最好还是加上后缀
System.out.println(file2.createNewFile());
}
}
package Demo_file;
import java.io.File;
public class Demo3_FileMethod {
/*
* 重命名与删除功能
* public boolean renameTo(File dest): 把文件重命名为指定的文件路径
* public boolean delete(): 删除文件或者文件夹
*
* 重命名注意事项
* 1.如果路径相同,就是改名
* 2.如果路径名不同,就是改名并剪切
*
* 删除注意事项
* 1.Java中的删除不走回收站
* 2.要删除一个文件夹,请注意文件内不能包含或者文件夹
*
*/
public static void main(String[] args) {
//demo1();
File file1 = new File("yyy.txt");
System.out.println(file1.delete());
File file2 = new File("aaa");
System.out.println(file2.delete());
File file3 = new File("ccc"); //如果删除一个文件夹,那么文件夹必须是空的
System.out.println(file3.delete());
}
public static void demo1() {
File file1 = new File("ooo.txt");
File file2 = new File("D:\\xxx.txt");
System.out.println(file1.renameTo(file2));
}
}
package Demo_file;
import java.io.File;
public class Demo4_Method {
/*
* 判断功能:
* public boolean isDirectory() : 判断是否是目录
* public boolean isFile() : 判断是否是文件
* public boolean exists() : 判断文件是否存在
* public boolean canRead() : 判断是否可读
* public boolean canWrite() : 判断是否可写
* public boolean isHidden() : 判断是否隐藏
*
*/
public static void main(String[] args) {
//demo1();
File file = new File("zzz");
file.setReadable(false);
System.out.println(file.canRead()); //windows系统中认为所有文件都是可读的
file.setWritable(false);
System.out.println(file.canWrite()); //windows系统可以设置为不可写
File file2 = new File("aaa.txt");
System.out.println(file2.isHidden());
System.out.println(file.isHidden());
}
public static void demo1() {
File dir1 = new File("ccc");
System.out.println(dir1.isDirectory()); //判断是否是文件夹
File dir2 = new File("zzz");
System.out.println(dir1.isDirectory());
System.out.println(dir1.isFile()); //判断是否是文件
System.out.println(dir2.isFile());
}
}
package Demo_file;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Demo5_FileMethod {
/*
* 获取功能:
* public String getAbsolutePath() :获取绝对路径
* public String getPath() : 获取路径
* public String getName() : 获取名称
* public long length() : 获取长度,字节数
* public long lastModified() : 获取最后一次的修改时间,毫秒值
* public String[] list() : 获取指定目录下的所有文件或者文件夹的名称数组
* public File[] listFiles() : 获取指定目录下的所有文件或者文件夹的File数组
*
*/
public static void main(String[] args) {
//demo1();
File dir = new File("D:\\File");
String[] arr = dir.list(); //仅为了获取文件名
for (String string : arr) {
System.out.println(string);
}
File[] subFiles = dir.listFiles(); //获取文件对象
for (File file : subFiles) {
System.out.println(file);
}
}
public static void demo1() {
File file1 = new File("ccc.txt");
File file2 = new File("D:\\File\\ccc.txt");
System.out.println(file1.getAbsolutePath()); //获取绝对路径
System.out.println(file2.getAbsolutePath());
System.out.println(file1.getPath()); //获取构造方法传入的路径
System.out.println(file2.getPath());
System.out.println(file1.getName()); //获取名称
System.out.println(file2.getName());
System.out.println(file1.length());
System.out.println(file1.lastModified()); //文件的最后修改时间
Date d = new Date(file1.lastModified());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
System.out.println(sdf.format(d));
}
}
以上是File这个类的构造方法和这个类的一些比较常用的方法。
IO流
流(Stream),是一个抽象的概念,是指一连串的数据(字符或字节),是以先进先出的方式发送信息的通道。
当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或是网络连接。类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流。这时候你就可以想象数据好像在这其中“流”动一样。
一般来说关于流的特性有下面几点:
先进先出:最先写入输出流的数据最先被输入流读取到。
顺序存取:可以一个接一个地往流中写入一串字节,读出时也将按写入顺序读取一串字节,不能随机访问中间的数据。
只读或只写:每个流只能是输入流或输出流的一种,不能同时具备两个功能,输入流只能进行读操作,对输出流只能进行写操作。在一个数据传输通道中,如果既要写入数据,又要读取数据,则要分别提供两个流。
IO流一般分为字节流和字符流。下来我就比较详细的介绍一下字节流和字符流。
字节流
package Demo_Stream.Demo_IO;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Demo1_IO {
/*
* 概念:
* 1.IO流用来处理设备之间的数据传输
* 2.Java对数据的额操作是通过流的方式
* 3.Java用于操作流的流的类都在IO包中
* 流按流向分为两种:输入流,输出流
* 流按操作类型分为两种:
* 字节流:字节流可以操作任何数据,因为计算机中任何数据都是以字节的形式存储的
* 字符流:字符流只能操作出字符数据,比较方便
* IO常用父类
* 字节流的抽象父类:
* InputStream
* OutputStream
* 字符流的抽象父类:
* Reader
* Writer
* 程序书写:
* 使用前:导入IO包中的类
* 使用时:进行IO异常处理
* 使用后:释放资源
* read()方法读取的是一个字节,为什么是int,而不是byte
* 因为字节输入流操作任意类型的文件,比如图片音频等,这些文件底层都是二进制形式存储的,如果每次读取都返回byte
* ,有可能再读到中间的时候遇到11111111,那么这11111111是byte类型的-1,我们的程序遇到-1就会停止不读了,后面的数据就读不到了
* 所以在读取的时候用int型接收,如果11111111会在其前面补上,24个0凑足4个字节,那么byte类型的-1就变成了int类型的255了
* 这样可以保证整个数据读完,而结束标记的-1就是int类型
*
*/
public static void main(String[] args) throws IOException {
//demo1();
//demo2();
}
private static void demo2() throws IOException {
FileInputStream fis = new FileInputStream("xxx.txt"); //创建流对象
int b;
while((b = fis.read()) != -1) {
System.out.println(b);
}
}
public static void demo1() throws FileNotFoundException, IOException {
FileInputStream fis = new FileInputStream("xxx.txt"); //创建流对象
int x = fis.read(); //从硬盘上读取一个字节
System.out.println(x);
int y = fis.read();
System.out.println(y);
int z = fis.read();
System.out.println(z);
int a = fis.read();
System.out.println(a);
int b = fis.read();
System.out.println(b);
fis.close(); //关流释放资源
}
}
package Demo_Stream.Demo_IO;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo2_FileOutPutStream {
public static void main(String[] args) throws IOException {
//demo2();
//demo1();
}
private static void demo2() throws IOException {
FileOutputStream fos = new FileOutputStream("yyy.txt",true); //如果想续写,就在第二个参数传true
fos.write(97);
fos.write(98);
fos.close();
}
private static void demo1() throws IOException {
FileOutputStream fos = new FileOutputStream("yyy.txt"); //创建字节输出流对象,如果没有就会自动创建一个
// fos.write(97); //虽然是一个int数,但是到文件上的是一个字节,会自动去除前三个8位
// fos.write(98);
// fos.write(99);
fos.write(100);
fos.close();
}
}
package Demo_Stream.Demo_IO;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo3_Copy {
public static void main(String[] args) throws IOException {
//demo1();
//第二种拷贝
//第二种拷贝不推荐使用,因为有可能内存溢出
FileInputStream fis = new FileInputStream("123345778.jpg"); //创建输入流对象
FileOutputStream fos = new FileOutputStream("copy.jpg"); //创建输出流对象
// int len = fis.available();
// System.out.println(len);
byte[] arr = new byte[fis.available()]; //创建与文件大小一样的字节数组
fis.read(arr); //将文件上的字节数读取到内存中
fos.write(arr); //将字节数组中的字节数据写到文件上
fis.close();
fos.close();
}
private static void demo1() throws IOException {
FileInputStream fis = new FileInputStream("123345778.jpg"); //创建输入流对象
FileOutputStream fos = new FileOutputStream("copy.jpg"); //创建输出流对象
int b;
while((b = fis.read()) != -1) { //在不断的读取每一个字节
fos.write(b); //将每一个字节输出
}
fis.close(); //关流释放资源
fos.close();
}
}
package Demo_Stream.Demo_IO;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo4_ArrayCopy {
/*
第三种拷贝
定义小数组
*/
public static void main(String[] args) throws IOException {
//demo1();
//demo2();
//demo3();
}
private static void demo3() throws IOException {
//利用小数组进行文件拷贝,将小数组定义为 1024 字节的整数倍。
FileInputStream fis = new FileInputStream("xxx.txt");
FileOutputStream fos = new FileOutputStream("yyy.txt");
byte[] arr = new byte[1024 * 8];
int len;
while ((len = fis.read(arr)) != -1) { //如果忘记加arr,返回的就不是读取的字节个数,而是字节的码表值
fos.write(arr, 0, len);
}
fos.close();
fis.close();
}
private static void demo2() throws IOException {
FileInputStream fis = new FileInputStream("xxx.txt");
FileOutputStream fos = new FileOutputStream("yyy.txt");
byte[] arr = new byte[2];
int len;
while((len = fis.read(arr)) != -1) {
fos.write(arr,0,len);
}
fos.close();
fis.close();
}
public static void demo1() throws IOException {
FileInputStream fis = new FileInputStream("xxx.txt");
byte[] arr = new byte[2];
int a = fis.read(arr); //将文件上的字节读取到字节数组中
System.out.println(a); //读到的有效字节个数
for (byte b : arr) { //第一次获取到文件上的a和b
System.out.println(b);
}
System.out.println("------------");
int c = fis.read(arr);
System.out.println(c);
for (byte b : arr) {
System.out.println(b);
}
fis.close();
}
}
package Demo_Stream.Demo_IO;
import java.io.*;
public class Demo5_BufferCopy {
/*
缓冲思想:
字节流一次读写一个数组的速度明显比一次读写一个字节的速度快很多,
这是加入了数组这样的缓冲区效果,java本身在设计的时候,也考虑到了这样的设计思想,所以提供了字节缓缓冲区流
BufferedInputStream
BufferedInputStream内置了一个缓冲区(数组)
从BufferedInputStream中读取一个字节时
BufferedInputStream会一次性从文件中读取8142个,存在缓冲区中,返回给程序一个
程序再次读取时,就不用找文件了,直接从缓冲区中获取
知道缓冲区中所有的都被使用过,才重新从文件中读取8192个
BufferedOutputStream
BufferedOutputStream也内置了一个缓冲区(数组)
程序向流中写出字节时,不会直接写到文件,先写到缓冲区
直到缓冲区写满,BufferedOutputStream才会把缓冲区中的一些数据一次性写到文件里
close方法
具备刷新功能,再关闭流之前,就会先刷新一次缓冲区,将缓冲区的字节全部刷新到文件上,再关闭,close方法刷完之后就不能写了
flush方法
具备刷新功能,刷完之后还可以继续写
*/
public static void main(String[] args) throws IOException {
//demo1();
//fiush和close方法的区别
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("yyy.txt"));
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("xxx.txt"));
int b;
while((b = bis.read()) != -1) {
bos.write(b);
}
bos.close();
bis.close();
}
private static void demo1() throws IOException {
FileInputStream fis = new FileInputStream("xxx.txt"); //创建输入流对象
FileOutputStream fos = new FileOutputStream("yyy.txt"); //创建输出流对象
BufferedInputStream bis = new BufferedInputStream(fis); //创建缓冲区对象,对输入流进行包装让其变得更加强大
BufferedOutputStream bos = new BufferedOutputStream(fos);
int b;
while((b = bis.read()) != -1) {
bos.write(b);
}
bis.close();
bos.close();
}
}
package Demo_Stream.Demo_IO;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class Demo6_Chinese {
/*
字节流读取中文的问题
字节流在读取中文的时候可能会读到半个中文
字节流写出中文的问题
字节流直接操作的字节,所以写出中文必须将字符串转换成字节数组
写出回车换行 write("\r\n".getBytes());
*/
public static void main(String[] args) throws IOException {
//demo1();
FileOutputStream fos = new FileOutputStream("yyy.txt");
fos.write("我读书少,你别骗我".getBytes());
fos.write("\r\n".getBytes());
fos.close();
}
private static void demo1() throws IOException {
FileInputStream fis = new FileInputStream("yyy.txt");
byte[] arr = new byte[4];
int len;
while((len = fis.read(arr)) != -1) {
System.out.println(new String(arr,0,len));
}
fis.close();
}
}
package Demo_Stream.Demo_IO;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo7_TryFinally {
/*
流的标准处理异常代码(1.6版本以前)
*/
public static void main(String[] args) throws IOException {
//demo1();
//JDK1.6版本之后使用这种方式去处理异常代码
try(
FileInputStream fis = new FileInputStream("xxx.txt");
FileOutputStream fos = new FileOutputStream("yyy.txt");
) {
int b;
while((b = fis.read()) != -1) {
fos.write(b);
}
}
}
private static void demo1() throws IOException {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("xxx.txt");
fos = new FileOutputStream("yyy.txt");
int b;
while ((b = fis.read()) != -1) {
fos.write(b);
}
} finally {
try {
if (fis != null)
fis.close();
} finally { //try finally的嵌套目的是能关一个尽量关一个
if (fos != null)
fos.close();
}
}
}
}
以上是字节流的一些东西,虽然没写什么内容,但代码中的注释就能够很好的介绍字节流的一些操作方法。
字符流
字符流是和字节流有点不同,字符流是通过将文本文件转换成字符进行操作,而字节流是通过每个字节进行操作。所以字符流有不同的标准,因为有不同的字符码表。
package Demo_cahrIO;
import java.io.FileReader;
import java.io.IOException;
public class Demo1_FIleReader {
public static void main(String[] args) throws IOException {
//demo1();
FileReader fr = new FileReader("xxx.txt");
int c;
while((c = fr.read()) != -1) { //通过项目默认的码表一次读取一个字符
System.out.print((char)c);
}
fr.close();
}
private static void demo1() throws IOException {
FileReader fr = new FileReader("xxx.txt");
int x = fr.read();
System.out.println(x);
char c = (char)x;
System.out.println(c);
fr.close();
}
}
package Demo_cahrIO;
import java.io.FileWriter;
import java.io.IOException;
public class Demo2_FileWriter {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("yyy.txt");
fw.write("大家好,这一学期接近尾声了,要坚持!!!");
fw.write(97);
fw.close();
}
}
package Demo_cahrIO;
import java.io.*;
public class Demo3_Copy {
/*
什么情况下使用字符流?
字符流也可以拷贝文件,但不推荐使用,因为读取时会把字节转换为字符,写出时还要把字符转会字节。
程序需要读取一段文本,或者需要写出一段文本的时候可以使用字符流
读取的时候是按照字符的大小读取的,不会出现半个中文
写出的时候可以直接将字符串写出,不用转换为字节数组
字符流不可以拷贝非纯文本的文件
因为在读的时候会将字节转为字符,在转换的过程中,可能找不到对应的字符,就会用?代替,写出的时候会将字符转成字节写出去
如果是?,直接写出,这样写出之后的文件就乱了
*/
public static void main(String[] args) throws IOException {
//demo1();
//demo2();
BufferedReader br = new BufferedReader(new FileReader("xxx.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("yyy.txt"));
int c;
while((c = br.read()) != -1) {
bw.write(c);
}
br.close();
bw.close();
}
private static void demo2() throws IOException {
FileReader fr = new FileReader("xxx.txt");
FileWriter fw = new FileWriter("yyy.txt");
int len;
char[] arr = new char[1024 * 8];
while((len = fr.read(arr)) != -1) {
fw.write(arr,0,len);
}
fr.close();
fw.close();
}
private static void demo1() throws IOException {
FileReader fr = new FileReader("xxx.txt");
FileWriter fw = new FileWriter("yyy.txt");
int x;
while((x = fr.read()) != -1) {
fw.write(x);
}
fr.close();
fw.close();
}
}
package Demo_cahrIO;
import java.io.*;
public class Demo4_Buffered {
/*
带缓冲区的特殊方法
readLine();
newLine();
newLine()与\r\n的区别
newLine()是跨平台的方法
\r\n只支持Windows系统
*/
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("xxx.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("yyy.txt"));
String line;
while((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
}
br.close();
bw.close();
}
}
package Demo_cahrIO;
import java.io.*;
public class Demo5_LineNumberReader {
//为文件添加一个行号
public static void main(String[] args) throws IOException {
LineNumberReader lnr = new LineNumberReader(new FileReader("xxx.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("yyy.txt"));
String line;
lnr.setLineNumber(0);
while((line = lnr.readLine()) != null) {
bw.write(lnr.getLineNumber() + ":" + line);
bw.newLine();
}
bw.close();
lnr.close();
}
}
这是根据不同的码表进行转换,使文件能通过不同的码表进行操作。
package Demo_cahrIO;
import java.io.*;
public class Demo7_TransIO {
public static void main(String[] args) throws IOException {
//demo1();
//demo2();
BufferedReader br = new BufferedReader(new InputStreamReader //更高效的读
(new FileInputStream("utf-8.txt"),"utf-8"));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter //更高效的写
(new FileOutputStream("gbk.txt"),"gbk"));
int c;
while((c = br.read()) != -1) {
bw.write(c);
}
br.close();
bw.close();
}
private static void demo2() throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("utf-8.txt"),"utf-8");
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"),"gbk");
int c;
while((c = isr.read()) != -1) {
osw.write(c);
}
isr.close();
osw.close();
}
private static void demo1() throws IOException {
//用默认编码表读写,会出现乱码
FileReader fr = new FileReader("utf-8.txt");
FileWriter fw = new FileWriter("gbk.txt");
int c;
while((c = fr.read()) != -1) {
fw.write(c);
}
fr.close();
fw.close();
}
}
以上就是文件的操作和IO流的简单介绍与一些操作,虽然写的不是很多,但是我觉得里面的内容还是很详细的,里面的代码很好的将这些操作进行了实践。