java.io.File类用于表示文件或者目录。
对于File类的对象的操作实际就为对存储介质中的文件和目录的操作。
File类的文件操作与操作系统平台无关。
构造方法
public File(String pathname)以pathname为路径创建File对象。
常用属性
public static final String separator: 存储当前系统的路径分隔符。UNIX:‘/‘,Windows:‘\\‘。为了跨平台文件路径应用这个属性代替。
访问属性的方法
public boolean canRead()
:判断文件是否可读
public boolean canWrite()
: 判断文件是否可写
public boolean exits()
: 判断文件是否存在
public boolean isDirectory()
:判断是否是目录
public boolean isFile()
: 判断是否为文件
public boolean isHidden()
: 判断文件是否隐藏
public long lastModified()
: 返回最后修改的时间
public long length()
: 返回文件以字节为单位的长度
public String getName()
:获取文件名
public String getPath()
:获取文件的路径
public String getAbsolutePath()
:获取此文件的绝对路径名。
public String getCanonicalPath()
:获取此文件的规范路径名。
public File getAbsoluteFile()
: 得到绝对路径规范表示的文件对象。
public String getParent()
:得到文件的父目录路径名
public URL toURL()
:返回此文件的统一资源标识符名
public static void main(String[] args) throws IOException {
File file = new File("D:\\IOTest\\source.txt");//指定目录要存在改文件
}
对文件的操作
public boolean createNewFile()
: 不存在时常见此文件对象所代表的空文件。public boolean delete()
:删除文件。必须目录为空才能删除public boolean mkdir()
:创建此抽象路径指定的目录。public boolean mkdirs()
: 创建此抽象路径指定的目录,同时创建父目录public boolean renameTo(File dest)
:重新命名为此抽象路径表示的文件浏览目录中的文件和子目录方法
public String[] list()
: 返回此目录中的文件和目录名的数组public File[] listFiles()
: 返回此目录中的文件和目录的File实例数组public File[] listFiles(FilenameFilter filter)
: 返回此目录中满足指定过滤器的文件和目录public static void main(String[] args) throws IOException{
File dir1 = new File("D:/IOTest/dir1");
if (!dir1.exists()) dir1.mkdir();//不存在就创建
File dir2 = new File(dir1, "dir2");//以dir1为父目录 名字为dir2
File dir4 = new File(dir1, "dir3/dir4");//以dir1,dir3为父目录 创建名字为dir4的目录
File file = new File(dir2, "test.txt");
if (!file.exists()) file.createNewFile();//不存在就创建
deleteAll(dir1);//删除目录
}
public static void deleteAll(File file){
if (file.isFile()) {
file.delete();//直接删除文件
return;
}
//是目录 则递归删除子目录和子文件
File[] lists = file.listFile();
for (int i = 0; i < lists.length; i++) {
deleteAll(list[i]);//则递归删除子目录和子文件
}
System.out.println("删除目录:"+ file.getAbsolutePath());
file.delete();
}
从数据源读数据时就要开启一个到数据源的流。
方便处理数据的输入输出。
java.io包中四种抽象流类:
InputStream
以字节为单位从数据源中读取数据
public abstract int read() throws IOException
: 从输入流中读取数据的下一个字节,返回读到的字节值。流的末尾返回-1public void close() throws IOException
:关闭输入流并释放系统资源OutputStream
以字节为单位向数据源写数据
public abstract void write(int b) throws IOException
:将指定的字节写入输出流public void write(byte[] b) throws IOException:
将b.length个字节从指定的byte数组写入此输出流public void flush() throws IOException
:刷新此输出流,并强制写出所有缓冲的输出字节public void close() throws IOException
:关闭输入流并释放系统资源Reader
以字符为单位从数据源中读取数据
Writer
以字符为单位向数据源写数据
public abstract void write(int b) throws IOException
:将指定的字符写入输出流public void write(char[] cbuf) throws IOException
: 写入字符数组public void write(String str) throws IOException
:写入字符串public void flush() throws IOException
:将缓冲数据全部写到目的地public void close() throws IOException
:先刷新再关闭FileInputStream、FileOutputStream、FileReader、FileWriter四个文件流。
FileInputStream、FileOutputStream
import java.io.*
public static void main(String[] args) {
FileInputStream fin = null;
try {
// 第一步:创建一个FileInputStream对象
fin = new FileInputStream("D:\\IOTest\\source.txt");
System.out.println("可读取的字节数" + fin.available());
//第二步:按字节读数据,返回的是读到的字节
int i = read();
while(i != -1) {
System.out.println((char)i);
i = fin.read();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null != fin)
fin.close();//关闭输入流
} catch (IOException e) {
e.printStackTrace();
}
}
}
Java字符采用Unicode,汉字占用两个字节,英文字符占一个用字节流读取会出乱码问题。
import java.io.*
public static void main(String[] args) {
FileInputStream out = null;
try {
//1.建立连接
out = new FileInputStream("D:\\IOTest\\source.txt");
//2.写数据
out.write("#");
out.write("hello word".getBytes());//字符串转换为字节数组
out.write("你好".getBytes());//字符串转换为字节数组
//3.刷新输出流
out.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null != out)
out.close();//关闭输入流
} catch (IOException e) {
e.printStackTrace();
}
}
}
IO流类的close方法会释放占有的系统资源,用来操作二进制文件比较合适,图片,声音,视频等二进制文件。
FileReader、FileWriter
以字符为操作单位的文件输入流和文件输出流。
常用于操作字符文本文件。
//实现字符文本的复制
import java.io.*
public static void main(String[] args) {
FileReader fr = null;
FileWriter fw = null;
int c = 0;
try {
fr = new FileReader("D:\\IOTest\\source.txt");
fw = new FileWriter("D:\\IOTest\\result.txt");
while((c = fr.read()) != -1) {
fw.write(c);
}
fw.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null != fw)
fw.close();//关闭输入流
if (null != fr)
fr.close();//关闭输入流
} catch (IOException e) {
e.printStackTrace();
}
}
}
为了更高的效率可以一次提取一个字节数组和写入一个字节数组。
int length = 0;//字符串长度
char []cbuf = new char[8192];
while((length = fr.reader(cbuf)) != -1) {
fw.write(cbuf, 0, length);//一次性写入
}
为了提高读写速率,提供带缓冲功能的流类,内部创建一个缓冲区数组。读取数据时,先把数据填充到该内部缓冲区,然后再返回;在写入数据前先放到缓冲区再一次性写入到目标数据源。
属于过滤流,不直接操作数据源,是对直接操作数据源的节点流的一个包装。
//用缓冲流来改写字符文本复制功能
public static void main(String[] args) {
BufferedReader br = null;
BufferedReader bw = null;
try {
//创建缓冲流对象:是过滤流,是对节点流的包装
br = new BufferedReader(new FileReader("D:\\IOTest\\source.txt"));
bw = new BufferedWriter(new FileWriter("D:\\IOTest\\source.txt"));
String str = null;
while ((str = br.readLine()) != null) { // 每次读取一行字符
bw.write(str); //一次写入一行字符串
bw.newLine(); //写入行分隔符
}
bw.flush();
}
}
关闭过滤流时会自动关闭所包装的底层节点流。
在字节和字符流之间转换。
InputStreamReader和OutputStreamWriter。
InputStreamReader
将字节流中读取到的字节按指定字符集解码成字符,需要和InputStream套接
InputStreamReader(InputStream in)
:使用默认字符集的InputStreamReaderInputStreamReader(InputStream in, String charsetName)
:使用指定字符集的InputStreamReaderOutputStreamWriter
将要写入字节流的字符按指定字符集编码成字节,需要和OutputStream套接
OutputStreamWriter(OutputStream in)
:使用默认字符编码的OutputStreamWriterOutputStreamWriter(OutputStream out, String charsetName)
:使用指定字符编码的OutputStreamWriterpublic static void main(String[] args) {
System.out.println("输入信息:按e或exit退出");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s = null;
try {
while(s = br.readLine() != null) {
if (s.equalsIgnoreCase("e")||s.equalsIgnoreCase("exit")) {
System.out.println("安全退出!!");
break;
}
System.out.println("-->:" + s.toUpperCase());
System.out.println("输入信息:按e或exit退出");
}
} catch {//异常处理
...
}
}
先把字节流包装成字符流,为了进一步提高效率,又把它包装成缓冲流。
为了方便操作java语言的基本数据类型的数据,可以使用数据流。
DataInputStream和DataOutputStream分别来读写出基本数据类型
public final boolean readBoolean()
: 从输入流中读取一个布尔型的值。public final byte readByte()
: 从输入流中读取一个8位的字节public final char readChar()
: 读取一个16位的Unicode字符public final float readFloat()
: 读取一个32位的单精度浮点数public final double readDouble()
: 读取一个64位的双精度浮点数public final short readShort()
: 读取一个16位的短整数public final int readInt()
: 读取一个16位的短整数public final long readLong()
: 读取一个64位的长整数public final void readFully(byte[] b):
从当前输入流中读取b.length个字节到该字节数组public final void readFully(byte[] b, int off, int len)
: 从当前数据流中读取len个字节到字节数组public final String readUTF()
: 读取一个UTF格式字符组成的字符串public int skipBytes(int n)
: 跳过n字节public static void main(String[] args) {
DataOutputStream dos = null;
try {
//创建连接到指定文件的数据输出流对象
dos = new DataOutoutStream(new FileOutputStream("d:\\IOTest\\destData.dat"));
dos.writeUTF("ab 中国");
dos.writeBoolean(false);
dos.writeLong(12345678L);
}
}
PrintStream和PrintWriter都属于打印流,提供一系列的print和println方法,可以实现将基本数据类型的数据格式转换成字符串进行输出。
PrintStream和PrintWriter不会抛出IOException异常
public class void main(String[] args) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(new File("d:\\IOTest\\text.txt"));
} catch(FileNotFoundException e) {
e.printStackTrace();
}
//创建打印输出流,设置为自动刷新模式(写入换行或字节‘\n‘都会刷新输出缓冲区)
PrintStream ps = new PrintStream(fos, true);
if (ps != null) {
//把标准输出流(控制台输出)改成文件
System.setOut(ps);
}
for (int i = 0; i <= 255; i++) {
System.out.print((char)i);
if (i % 50 == 0) {
System.out.println();//换行
}
}
ps.close();
}
ObjectOutputStream和ObjectInputStream类是用于存储和读取基本数据类型或对象的过滤流,可以把Java 的对象写入到数据源中,也能把对象从数据源中还原回来。
用ObjectOutputStream保存基本数据类型或对象的机制叫做序列化。
用ObjectInputStream读取基本数据类型或对象的机制叫做反序列化。
ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量,能被序列化的对象所对应的类必须实现java.io.Serializable这个标识性接口。
public class Student implements java.io.Serializable {
private int id;
private String name;
private transient int age; //在序列化的时候不会被保存和读取
public Student(){}
public student(int id, int age, String name) {
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {return id;}
public int getAge() {return age;}
public String toString() {return "id="+id ,",name="+name,",age="+age;}
}
//创建一个学生对象并序列化到一个文件objectSeri.dat
public static void main(String[] args) {
ObjectOutputStream oos = null;
try {
// 创建连接到指定文件的对象输出流实例
oos = new ObjectOutputStream(new FileOutputStream("D:\\IOTest\\objectSeri.dat"));
oos.write(new Student(101, 22,"张三"));
oos.flush(); //刷新输出流
System.out.println("序列化成功");
} catch ()//异常处理
}
//把指定文件中的数据反序列化回来,并打印输出它的信息
public static void main(String[] args) {
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("D:\\IOTest\\objectSeri.dat"));
Student stu = (Student) ois.readObject();//读取对象
System.out.println(stu);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
ois.close();
}
}
RandomAccessFile 是一个特殊的流类,它可以在文件的任何地方读取或写入数据。打开后可以进行只读操作或者读写操作。
在第二个参数指定操作方式: r,rw,rws,rwd.
RandomAccessFile in = new RandomAccessFile("d:\\IOTest||music.wmv", "r");
RandomAccessFile inout = new RandomAccessFile("d:\\IOTest||music.wmv", "rwd");
类似存在一个文件指针,该文件指针标志将要读写操作的下一个字节的位置, getFilePointer()方法可以返回文件指针的当前位置。seek方法可以将文件指针移动到文件内部的任意字节位置。
随机存取文件流只能操作磁盘文件,不能访问来自网络或内存映像的流。
RandomAccessFile类的多线程下载程序
import java.io.*
import java.net.*
public class MutiThreadDownloadTest{
public static void main(String[] args) thorws IOException{
String urlStr = "http://...sss.mp3" ;//资源地址
URL url = new URL(urlStr); //创建URL
URLConnection con = url.openConnection(); //建立连接
int contentLen = con.getContentLength(); //获取连接资源总长度
int threadQut = 10; //线程数
int subLen = contentLen / threadQut;// 每个线程要下载的大小
int remainder = contenLen % threadQut; // 余数
File destFile = new File("D:\\IOTest\\sss.mp3"); //目标文件
for (int i = 0; i < threadQut; i++) {
int start = subLen * i; //从目标文件的start位置开始写入到end结束总共subLen个字节
int end = start + subLen - 1;
if (i == threadQut - 1) { //最后一次要加上余数
end += remainder;
}
Thread t = new Thread(new DownloadRunnable(start, end, url, destFile));//开启一个新线程
t.start();//启动新线程
}
}
}
public class DownloadRunnale implements Runnable {
private final int start;
private final int end;
private final URL srcURL;
private final File destFile;
private static final int BUFFER_SIZE = 8192; //缓冲区大小
public DownloadRunnale(int start, int end, URL srcURL, FILE destFile){
this.start = start;
this.end = end;
this.srcURL = srcURL;
this.destFile = destFile;
}
public void run() {
System.out.println("Thread.currentThread().getName()" + "启动");
BufferedInputStream bis = null;
RandomAccessFile ras = null;
byte[] buf = new byte[BUFFER_SIZE];
URLConnection con = null;
try {
con = srcURL.openConnection();
con.setRequestProperty("Range","byte="+start+"-"+end);
bis = new BufferedInputStream(con.getInpputStream());
ras = new RandomAccessFile(destFile,"rw");
ras.seek(start);
int len = -1;
while ((len = bis.read(buf)) != -1) {
ras.write(buf, 0, len);
}
System.out.println(Thread.currentThread().getName() + "下载完毕");
}
}
}
原文:https://www.cnblogs.com/DengSchoo/p/12831649.html