字节流
一些注意点:
英文 1字节
中文 gbk utf-8 2字节、3字节
相对路径———项目下寻找
File
❑ File类:文件和目录路径名的抽象表现形式
❑ 作用:通过File对象实现对文件或者文件夹的操作 ❑ 常用构造方法:
❑File(String URL)
❑ 常用方法: ❑String getName() --- 获取当前文件对象的名字
❑long length() --- 获取文件对象的大小 单位:字节
❑boolean isFile()/isDirectory()--- 判断文件/文件夹
❑boolean canRead()/canWrite()--- 判断文件可读/可写
❑boolean isHidden() --- 判断file对象是否为隐藏
❑long lastModified() --- 获取当前file对象最后修改时间
public class TestFile02 { public static void main(String[] args) { // test01(); // test02(); File file = new File("A"); test03(file); } private static void test03(File file) { if(file.isDirectory()) { //如果是文件夹,遍历 File[] files = file.listFiles(); for (File file2 : files) { //继续判断文件类型 test03(file2); } //删除空的文件夹 file.delete(); }else { //只要是文件,直接删除 file.delete(); } } private static void test02() { File file = new File("test01.txt"); System.out.println(file.exists()); if(!file.exists()) { try { file.createNewFile(); //创建文件 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } File file2 = new File("A"); if(!file2.exists()) { //创建文件夹 // file2.mkdir();//只能创建单层文件夹 file2.mkdirs();//创建多层文件夹 } //删除文件或者文件夹 //删除文件的时候,不管有没有内容都会删除 //删除文件夹的时候,只能删除空文件夹 // file.delete(); file2.delete(); //获取子文件 File[] files = file2.listFiles(); System.out.println(files); for (File file3 : files) { System.out.println(file3); } } private static void test01() { // 相对路径:从项目底下去找 // 绝对路径:从盘符去找 // File file = new File("src\\cn\\goktech\\test02.txt"); File file = new File("D:" + File.separator + "源码\\龙岩实训\\LYSE进阶01\\src\\cn\\goktech\\test03.txt"); System.out.println(file); // 获取绝对路径 System.out.println(file.getAbsolutePath()); // 判断文件是否存在 System.out.println(file.exists()); // 获取文件名 System.out.println(file.getName()); // 获取文件大小 System.out.println(file.length()); // 判断是否是文件/文件夹 System.out.println(file.isFile()); System.out.println(file.isDirectory()); // 判断可读 System.out.println(file.canRead()); // 判断可写 System.out.println(file.canWrite()); // 判断是否隐藏 System.out.println(file.isHidden()); // 获取最后的修改时间 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String time = sdf.format(new Date(file.lastModified())); System.out.println(time); } }
File类常用方法
➢ 常用变量:File.separator –目录分隔符(/)
➢ 常用方法: • boolean exists() -- 判断文件是否存在
• void createNewFile() -- 创建新文件
• void mkdir()/mkdirs() – 创建新文件夹
• delete() – 删除文件或者文件夹
• File[] listFiles() – 获取当前文件夹下所有的子项,如果当前文件下为空则返回null值
FileFilter和FilenameFilter
❑ 文件过滤器 来获取一个目录下 满足条件的部分子选项(即只获取文件或只获取 目录)
❑ 文件过滤器更多是被用于listFiles(FileFilter filter)的参数中。
❑ FileFilter接口: public boolean accept(File pathname)
❑ FilenameFilter接口: public boolean accept(File dir, String name)
public class TestFilter03 { public static void main(String[] args) { File file = new File("D:\\工作\\授课\\龙岩实训"); // File[] files = file.listFiles(new FileFilter() { // // @Override // public boolean accept(File pathname) { //// System.out.println(pathname); // return pathname.getName().endsWith(".xlsx"); // } // }); File[] files = file.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { // System.out.println(dir); // System.out.println(name); return name.endsWith("xlsx"); } }); for (File file2 : files) { System.out.println(file2); } } }
RandomAccessFile类
➢ RandomAccessFile支持访问文件随机的读入和读取 ➢ 构造函数: • RandomAccessFile(File file , String mode) • RandomAccessFile(File file , String mode) 参数说明: 1、第一个参数:要访问的文件对象/文件路径 2、第二个参数:读写模式(r:只读模式;rw:可读可写) • 常用方法: ◆ read() – 从此文件中读取一个数据字节 ◆ write(int b) – 向此文件中写入指定的字节 ◆ read()和write()都有多个重载的方法,详见API 写入字符串乱码- - 转。g e t B y t e
Byte[] b = new Byte[2];
read(b) 一丛读取多少
syso.....(new Strng(bt))转中文
RandomAccessFile类
➢ 利用RandomAccessFile类提供的方法可以进行对文件指针的操作 ➢ 方法说明: • long getFilePoint():获取该文件当前的指针位置 • void seek(long pos):该方法允许我们将指针移动到指定位置 • 常用地方: ◆ 结合多线程对文件进行多点复制(迅雷下载)
public class TestRandomAccessFile04 { public static void main(String[] args) { File file = null; RandomAccessFile raf = null; try { file = new File("test01.txt"); raf = new RandomAccessFile(file, "rw"); //写数据 raf.write(65); raf.write(65); raf.write(65); // raf.writeUTF("国科科技"); //先将字符串转成字节数组 raf.write("国科科技".getBytes()); //获取指针位置 System.out.println(raf.getFilePointer()); //设置指针位置 raf.seek(3); System.out.println(raf.getFilePointer()); //读数据(当读到文件末尾返回-1) // System.out.println((char)raf.read()); // System.out.println((char)raf.read()); // System.out.println((char)raf.read()); //可以利用以一次性读多个字节读取中文 // byte[] bt = new byte[4]; // System.out.println(raf.read(bt)); // System.out.println(new String(bt)); byte[] bt = new byte[1024]; int i= 0; while((i=raf.read(bt))!=-1) { System.out.println(new String(bt,0,i)); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { if (raf != null) { try { raf.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
InputStream类(字节输入流)
❑ 抽象类 以字节为基本单元
InputStream方法
FileInputStream
作用:从实际磁盘中读取文件的内容,从文件系统中的某个文件获得输入字节 (*用于读取图像数据之类的原始字节流) ➢ 构造方法 • FileInputStream(File file) • FileInputStream(String name)
OutputStream
FileOutputStream
❑ 把流写入到文件。 ❑ 构造方法 FileOutputStream(File file) FileOutputStream(File file, boolean append) FileOutputStream(String name) FileOutputStream(String name, boolean append) append:如果文件已经存在,append=true表示往文件追加内容,否则会覆盖 文件。 ❑ 举例:拷贝文件
public class TestInAndOut { public static void main(String[] args) { File file = new File("test02.txt"); // testInputStream(file); // testOutputStream(file); testCopy(); } private static void testCopy() { InputStream in = null; OutputStream out = null; try { long start = System.currentTimeMillis(); in = new FileInputStream("头饰.png"); out = new FileOutputStream("copy.png"); int i = 0; byte[] bt = new byte[1024]; while((i=in.read(bt))!=-1) { out.write(bt); } System.out.println("复制完成...."); long end = System.currentTimeMillis(); System.out.println(end-start); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } private static void testInputStream(File file) { //输入流:从文件读取到系统内存 InputStream in = null; try { in = new FileInputStream(file); // System.out.println(in.read()); byte[] bt = new byte[1024]; int i= 0; while((i=in.read(bt))!=-1) { System.out.println(new String(bt,0,i)); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } private static void testOutputStream(File file) { //输出流:从系统内存写入到文件 OutputStream out = null; try { //append:true表示追加 out = new FileOutputStream(file,true); out.write(65); out.write(65); out.write(65); out.write(65); out.write(65); out.write("国科科技".getBytes()); System.out.println("写入完成。。。。"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
流的套接
❑ 流类可以分为 ❑底层流 包含以字节的形式读写的方法 ❑高层过滤器流 用于读写高层信息 ❑ 高层流要求底层流作为基础 ❑ 常用高层字节流: ❑DataInputStream ❑BufferedInputStream ❑ObjectInputStream
高级(过滤)流
❑ FilterInputStream/FilterOutputStream 类的子类包括
• DataInputStream/DataOutputStream ◆ DataInputStream和DataOutputStream提供多种多样的readxxx和writexxx方法是对多种数据的读写。 • BufferedInputStream/BufferedOutputStream ◆ 缓冲字节输入/输出流为InputStream/OutputStream对象增加了缓冲区功能,利用缓冲流可以增 加字节读写的速率,提升应用程序的性能 • PushbackInputStream/PushbackOutputStream
DataInputStream/DataOutputStream
❑ 提供读取/写入多种数据的能力 readXXX();writeXXX() ❑ 构造方法 DataInputStream(InputStream in) DataOutputStream(OutputStream out) ❑ DatainputStream/DataOutputStream中文乱码问题 ❑数据流如果用read/write方法读写中文,有可能会出现乱码问题,解决方法: ❑ String构造方法可以指定对byte数组做其他编码方式的解码,如 new String(bytes,”gbk”);同 时也可以使用readUTF和writeUTF方法解决乱码问题
public class TestData05 { public static void main(String[] args) { File file = new File("test01.txt"); // testWrite(file); testRead(file); } private static void testRead(File file) { InputStream in = null; DataInputStream dis = null; try { in = new FileInputStream(file); dis = new DataInputStream(in); System.out.println(dis.readChar()); System.out.println(dis.readUTF()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } private static void testWrite(File file) { DataOutputStream dos = null; OutputStream out = null; try { //创建字节输出流 out = new FileOutputStream(file); //创建高级流,将普通流添加进去 dos = new DataOutputStream(out); dos.writeChar('国'); dos.writeUTF("龙岩学院"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
BufferedInputStream/BufferedOutputStream
➢ 缓冲输入/缓冲输出 ➢ BufferedInputStream支持 mark 和 reset 方法 ➢ 构造方法: • BufferedInputStream(InputStream in) • BufferedInputStream(InputStream in, int size) ➢ 常用方法: • read(bytes[] b,int offset,int length) ◆ 第一个参数:构建缓冲区数组 ◆ 第二个参数:读取文件的起始位置 ◆ 第三个参数:每次读取文件的长度 • mark方法和reset方法 ◆ mark(int readlimit):在输入流的当前位置做标记,配合reset方法的后续调用将此流重新定位在最后标记的位置上,以便后续读取操作重新读取相同的字节 ◆ reset():将此流重新定位到对此输入流最后使用mark方法时的位置
BufferedOutputStream
➢ BufferedOutputStream常用方法: • flush():这是每个输出流都有的方法,作用为刷新此输出流 • write(bytes[] b,int offset,int length): ◆ 第一个参数:构建缓冲区数组 ◆ 第二个参数:写入文件的起始位置 ◆ 第三个参数:每次写入文件的长度 • write(int b):将指定字节b写入此缓冲的输出流中
PrintStream
➢ 方便地打印各种数据值表示形式 ➢ 与其他输出流不同,PrintStream 不会抛出 IOException;而是,异常情况仅设 置可通过 checkError 方法测试的内部标志。 ➢ 支持自动刷新;这意味着可在写入字节数组之后自动调用 flush 方法,可调用其 中一个 println 方法,或写入一个新行字符或字节 (‘\n’)。
public class TestBuffer06 { public static void main(String[] args) { File file = new File("test01.txt"); // testWrite(file); testRead(file); } private static void testRead(File file) { InputStream in = null; BufferedInputStream bis = null; try { in = new FileInputStream(file); bis = new BufferedInputStream(in); int i = 0; byte[] bt = new byte[1024]; while((i=bis.read(bt))!=-1) { System.out.println(new String(bt,0,i)); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } private static void testWrite(File file) { OutputStream out = null; BufferedOutputStream bos = null; try { out = new FileOutputStream(file); bos = new BufferedOutputStream(out); bos.write("福建国科信息科技有限公司".getBytes()); //刷新 bos.flush(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { try { bos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
字符流
配置文件
❑ 是一个文件,后缀一般为ini、properties或者xml文件
❑ 作用:用户登录时定义加载环境所需的设置和文件的集合
❑ 格式 键=值 ...... ➢ 例如 user=qq
读取配置文件 FileInputStream fis = new FileInputStream(“config.ini”); Properties prop = new Properties(); //从文件中加载配置 prop.load(fis); //根据键名取值 String user = prop.getProperty(“user”); www.goktech.cn 10 修改并保存配置到文件 //修改健名为user的健值admin,如果健名不存在, //则新增。 prop.setProperty("user", "admin"); ... //把prop里的健值对保存到文件config.ini FileOutputStream fos = new FileOutputStream("config.ini"); prop.store(fos, “备注”);
Reader
FileReader
➢ 使读取字符文件成为可能
➢ 构造方法 • FileReader(File file) • FileReader(String fileName)
BufferedReader
➢ 从字符输入流中读取文本,缓冲各个字符,从而提供单个字符、数组和字符串的 高效写入。
➢ 构造方法:BufferedReader(Reader r) ➢ readLine() 从流中读一行
Writer
FileWriter
➢ 允许将字符类型数据写入文件
➢ 构造方法 ➢ FileWriter(File file); ➢ FileWriter(String fileName);
BufferedWriter
❑ 将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高 效写入。 ❑ newLine() ❑ write(String s, int off, int len) ❑ 除非要求提示输出,否则建议用 BufferedWriter 包装所有其 write() 操作可 能开销很高的 Writer(如 FileWriters 和 OutputStreamWriters)。例如, PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));
字节流和字符流转换
➢ InputStreamReader 把字节输入流转换成字符流
➢ OutputStreamWriter 把字符流写到字节流
➢ 例子:用字节流打开文件,然后转成字符流 FileInputStream fis = new FileInputStream("e:/student.c"); InputStreamReader isr = new InputStreamReader(fis);
获取键盘输入
//System.in是键盘输入流 //把键盘输入转成字符流 InputStreamReader isr = new InputStreamReader(System.in); //用缓冲字符流封装,以允许读一行 BufferedReader br = new BufferedReader(isr); //从键盘读取一行 String line = br.readLine();
public class test { public static void main(String[] args) { // TODO Auto-generated method stub File file = new File("text.text"); test01(file); test02(file); } private static void test02(File file) { // TODO Auto-generated method stub OutputStream os= null; OutputStreamWriter osw = null; BufferedWriter bw = null; try { os = new FileOutputStream(file); osw = new OutputStreamWriter(os,"utf-8"); osw.write("三好学生"); bw =new BufferedWriter(osw); bw.write("全额奖学金"); bw.flush(); } catch (Exception e) { // TODO: handle exception } } private static void test01(File file) { //字节流字符流转换 //注意文件的编码格式。如果不相同会产生乱码。可以转字节流 //将字节的输入流转换成字符输入流 InputStream in = null; InputStreamReader isr = null; BufferedReader br =null; try { in = new FileInputStream(file); isr = new InputStreamReader(in,"utf-8");//可以指定读取的编码格式 System.out.println((char)isr.read());//不指定采用系统的编码格式 //也可以使用缓冲流 br = new BufferedReader(isr); System.out.println(br.readLine()); } catch (Exception e) { // TODO: handle exception } } } private static void testSystem() { //高级流可以使用 InputStreamReader isr = new InputStreamReader(System.in); BufferedReader reader = new BufferedReader(isr); try { System.out.println(reader.readLine()); } catch (Exception e) { // TODO: handle exception } }
序列化
➢ 序列化是把一个对象的状态写入一个字节流的过程。 ➢ 如果一个对象引用到其它对象,而这些对象又引用另外的对象,那么所有这些对 象都会被序列化。
Serializable接口
➢ 只有实现Serializable接口的对象才能被序列化工具存储或者恢复。 ➢ 声明为transient的变量不被序列化工具存储。 ➢ static变量同样不被存储。
ObjectOutputStream
➢ 构造方法 public ObjectOutputStream(OutputSteam os) ➢ 负责向流写入对象 public void writeObject(Object obj)
ObjectInputStream
➢ 构造方法 public ObjectInputStream(InputSteam is) ➢ 负责从流读出对象(反序列化) public Object readObject()
序列化
public class demo02 { public static void main(String[] args) { People p1 = new People(1,"小明","男",20,"1992-02-18","福建福州"); People p2 = new People(2,"小红","女",20,"1992-02-18","福建厦门"); File file = new File("People.text"); FileOutputStream fos = null; ObjectOutputStream oos = null; FileInputStream fis = null; ObjectInputStream ois = null; //序列化 try { fos = new FileOutputStream(file); oos = new ObjectOutputStream(fos); oos.writeObject(p1); oos.writeObject(p2); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { try { oos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //反序列化 try { fis = new FileInputStream(file); ois = new ObjectInputStream(fis); People p3 = (People)ois.readObject(); People p4 = (People)ois.readObject(); System.out.println(p3.toString()); System.out.println(p4.toString()); } catch (Exception e) { // TODO: handle exception } } } public class People implements Serializable{ private int no; private String name; private String sex; private int age; private String date; private String address; public People(int no, String name, String sex, int age, String date, String address) { super(); this.no = no; this.name = name; this.sex = sex; this.age = age; this.date = date; this.address = address; } @Override public String toString() { return "People [no=" + no + ", name=" + name + ", sex=" + sex + ", age=" + age + ", date=" + date + ", address=" + address + "]"; } }