import java.io.*
import java.io.File; public class TestFile { public static void main(String[] args) { File file = new File("C:/Users/hzw/Desktop/carat/yi.txt"); File file1 = new File("yi.txt"); File file2 = new File("/yi.txt"); System.out.println(file.exists()); System.out.println(file.isFile()); System.out.println(file.isDirectory()); //无论文件存不存在,名称都是yi.txt System.out.println(file.getName()); //绝对路径 System.out.println(file.getAbsolutePath()); //"yi.txt" : 项目所在路径+yi.txt System.out.println(file1.getAbsolutePath()); //"/yi.txt" : Linux(Unix)中 根路径+yi.txt ; Windows中 项目所在盘符+yi.txt System.out.println(file2.getAbsolutePath()); System.out.println(file.length());//0 } }
import java.io.File; import java.io.IOException; public class TestFile1 { public static void main(String[] args) throws IOException { File file = new File("C:/Users/hzw/Desktop/carat/yi"); //创建 boolean newFile = file.createNewFile(); System.out.println(newFile); //删除 boolean delete = file.delete(); System.out.println(delete); //遍历打印 File file1 = new File("C:\\Users\\hzw\\Desktop"); //public File[] listFiles() File[] files = file1.listFiles(); for (File file2 : files) { System.out.println(file2.getName()); } System.out.println(); //public String[] list() String[] list = file1.list(); for (String s : list) { System.out.println(s); } } }
import java.io.File; import java.io.IOException; public class TestFile1 { public static void main(String[] args) throws IOException { File file = new File("writerData.txt"); //创建 boolean newFile = file.createNewFile(); System.out.println(newFile); //删除 boolean delete = file.delete(); System.out.println(delete); //遍历打印 File file1 = new File("C:\\Users\\hzw\\Desktop"); //public File[] listFiles() File[] files = file1.listFiles(); for (File file2 : files) { System.out.println(file2.getName()); } System.out.println(); //public String[] list() String[] list = file1.list(); for (String s : list) { System.out.println(s); } } }
I(Input)输入,O(Out)输出
数据在各个设备之间的传输,是通过流的方式完成的
根据流动方向的不同,流分为输入流和输出流(相对于内存,输入和输出)
根据流的格式不同,流分为字节流和字符流
程序中的输入和输出都是以流的形式保存的,流中保存的实际上全是字节文件。
所有文件的存储都是字节(byte)来存储,在磁盘上保留的并不是文件的字符,而是先把字符编码成字节,再存储这些字节到硬盘上,在读取时也是一个一个的读取以形成序列
InputStream字节输入流, OutputStream字节输出流
派生出来的子类名称都是以其父类名作为子类名的后缀
如:InputStream的子类FileInputStream
Reader 字符输入流, Writer字符输出流
派生出来的子类名称都是以其父类名作为子类名的后缀
如:Reader的子类FileReader
Writer抽象类里的方法
由于Writer是抽象类不能创建对象,所以用它子类来完成写入字节的操作
FileWriter类是Writer的子类,是文件写入流,以字符流的形式对文件进行写操作,其构造方法有5种重载,以下是常用的4种:
换行符
不同操作系统换行符:
windows下的文本文件换行符:\r\n
linux/unix下的文本文件换行符:\n
Mac下的文本文件换行符:\r
要用System.getProperty(“line.separator”)代替 固定格式的换行符
具备平台无关性 ; 一次编写,到处运行 ; 更保险
/* Writer类是所有字符输出流的父类 */ import java.io.FileWriter; import java.io.IOException; /** * 字符文件输出流 FileWriter */ public class FileWriterTest { //定义常量,保存换行符 private static final String LIN_SEPARATOR = System.getProperty("line.separator"); public static void main(String[] args) { // public FileWriter(String fileName, boolean append) throws IOException {} FileWriter wr = null; try { ////append参数 表示是否追加,true追加 false 覆盖 wr = new FileWriter("writerData1.txt", false); //显示ASCII码 wr.write(89);/*Y*/ wr.write(74);/*J*/ wr.write(LIN_SEPARATOR); //wr.write(97+LIN_SEPARATOR); wr.write("175269588" + LIN_SEPARATOR); //写入字符串的某一部分 wr.write("SEVENTEEN", 1, 3);/*EVE*/ //public void write(String str, int off, int len) throws IOException {} wr.write(LIN_SEPARATOR); //public void write(char cbuf[]) throws IOException {} wr.write(new char[]{'c', 'a', 'r'});/*car*/ //刷新缓冲区,数据立刻写入文件 wr.flush(); } catch (IOException e) { e.printStackTrace(); } finally { if (wr != null) { try { //关闭FileWriter对象 wr.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
Reader抽象类里的方法
由于Reader是抽象类不能创建对象,所以用它子类来完成写入字节的操作
FileReader类是Reader的子类,文件读取流,允许以字符流的形式对文件进行读操作,其构造方法有3种重载方式,以下是常用的2种:
案例:
/* Reader 类是所有字符流输入类的父类 */ import java.io.FileReader; import java.io.IOException; /** * 字符文件输入流 FileReader */ public class FileReaderTest { public static void main(String[] args) { readData1(); readData2(); } //自定义长度读取,public int read(char cbuf[]) throws IOException{} private static void readData1() { FileReader fr = null; try { //创建FileReader对象 fr = new FileReader("writerData.txt"); //定义数组 char[] buffer = new char[24]; //每次读到数据的数量 int num; //把流中的数据循环到数组缓存中 while ((num = fr.read(buffer)) != -1) {/*-1 : 数据读完*/ //数组缓存中数据变成字符串 String s = new String(buffer, 0, num); // public String(char value[], int offset, int count) {} System.out.println(s); } System.out.println("读取完毕"); } catch (IOException e) { e.printStackTrace(); } finally { if (fr != null) { try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } } //不推荐,一次读一个字符 public int read() throws IOException {} private static void readData2() { FileReader fr = null; try { fr = new FileReader("writerData.txt"); int ch; //每次读入一个字符(fr.read()返回值是字符的编码值) while ((ch = fr.read()) != -1) {/*-1 : 数据读完*/ System.out.print((char) ch); } System.out.println("读取完毕"); } catch (IOException e) { e.printStackTrace(); } finally { if (fr != null) { try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
案例
import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class FileReaderAndFileWriterCopyTest { public static void main(String[] args) { copyFile(); } /** * 利用FileReader.read(char[] ch)方法读取原始文件的数据 * 利用FileWriter.write(char[] ch)方法向新文件中写数据 */ public static void copyFile() { FileReader fr = null; FileWriter fw = null; try { fr = new FileReader("writerData.txt"); fw = new FileWriter("copy.txt", true); int num; char[] buffer = new char[8]; //边读边写 while ((num = fr.read(buffer)) != -1) { //写入数据到流中 fw.write(buffer, 0, num); }//刷新,把缓冲区的数据写入文件中 fw.flush(); } catch (IOException e) { e.printStackTrace(); } finally { if (fr != null) { try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } if (fw != null) { try { fw.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
BufferedWriter类里有一个方法要注意
案例
import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; public class BufferedWriterTest { public static void main(String[] args) { FileWriter fw = null; BufferedWriter bw = null; try { fw = new FileWriter("bufferedWriter.txt"); bw = new BufferedWriter(fw); for (int i = 0; i < 4; i++) { bw.write("carat" + i); //行分隔符号(换行) bw.newLine(); } bw.flush(); } catch (IOException e) { e.printStackTrace(); } finally { if (fw != null) { try { fw.close(); } catch (IOException e) { e.printStackTrace(); } } if (bw != null) { try { bw.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
BufferedReader类里有一个方法要注意
案例
package com.tjetc.reader; import java.io.*; public class BufferedReaderTest { public static void main(String[] args) { FileReader fr = null; BufferedReader br = null; try { fr = new FileReader("bufferedWriter.txt"); br = new BufferedReader(fr); String str; //readLine()读取一行,返回字符串,如果返回null,说明数据已读完 while ((str = br.readLine()) != null) { System.out.println(str); } } catch (IOException e) { e.printStackTrace(); } finally { if (fr != null) { try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } } } } /* carat0 carat1 carat2 carat3 */
案例
import com.tjetc.IOUtils; import java.io.*; /** * BufferedWriter 与 BufferedReader 实现文件的复制 */ public class BufferedReaderWriterTest { public static void main(String[] args) { FileReader fr = null; FileWriter fw = null; BufferedReader br = null; BufferedWriter bw = null; try { fr = new FileReader("writerData.txt"); fw = new FileWriter("jinng.txt"); br = new BufferedReader(fr); bw = new BufferedWriter(fw); //边读边写 String str = br.readLine(); while (str != null) { bw.write(str); //换行 bw.newLine(); //读取一行 str = br.readLine(); } bw.flush(); } catch (IOException e) { e.printStackTrace(); } finally { //封装重复的方法到一个类中 IOUtils.close(bw); IOUtils.close(br); IOUtils.close(fw); IOUtils.close(fr); } } }
import java.io.IOException; import java.io.Reader; import java.io.Writer; public class IOUtils { public static void close(Writer w) { if (w != null) { try { w.close(); } catch (IOException e) { e.printStackTrace(); } } } public static void close(Reader r) { if (r != null) { try { r.close(); } catch (IOException e) { e.printStackTrace(); } } } }
OutputStream它不仅可以写入字节,字符,还可以写入图片等媒体文件
由于OutputStream是抽象类不能创建对象,所以用它子类来完成写入字节的操作
用OutputStream的子类java.io.FileOutputStream向文件中写入字节
FileOutputStream类的构造方法有5种重载方式,以下是常用的4种
案例
import java.io.FileOutputStream; import java.io.IOException; public class FileOutputStreamTest { public static void main(String[] args) { FileOutputStream fos = null; //创建 FileOutputStream 对象 try { fos = new FileOutputStream("data.txt"); //void write(int b) fos.write(98); //void write(byte b[]) fos.write("abc".getBytes()); //void write(byte b[], int off, int len) fos.write("171717".getBytes(), 1, 3); //字节流不用刷新,FileOutputStream虽然也有flush方法,但方法里是空的 fos.flush(); } catch (Exception e) { e.printStackTrace(); } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } } /*data文件内的内容 * babc717 */
InputStream它不仅可以读取字节,字符,还可以读取图片等媒体文件
由于IntputStream是抽象类不能创建对象,所以用它子类来完成写入字节的操作
FileOutputStream类的构造方法有3种重载方式,以下是常用的2种
构 造 方 法 | 说 明 |
---|---|
FileInputStream(File file) throws FileNotFoundException | 使用File对象创建文件输入流对象,如果文件打开失败,将抛出异常 |
FileInputStream(String name) throws FileNotFoundException | 使用文件名或路径创建文件输入流对象,如果文件打开失败,将抛出异常 |
有一个 data.txt 文件,下面使用 FileInputStream 类读取并输出该文件的内容。具体代码如下:
import java.io.FileInputStream; import java.io.IOException; public class FileInputStreamTest { public static void main(String[] args) { fileInputStreamByReadChar(); fileInputStreamByRead(); } /** * public int read(byte b[]) throws IOException {} * 从输入流中读取若干字节,并把它们保存到参数 b 指定的字节数组中。 * 该方法,返回读取的字节数。 * 如果返回 -1,则表示已经到了输入流的末尾 */ public static void fileInputStreamByReadChar() { FileInputStream fis = null; try { fis = new FileInputStream("data.txt"); byte[] b = new byte[1024]; int num = fis.read(b); while (num != -1) { String s = new String(b, 0, num); System.out.println(s);/*babc717*/ num = fis.read(b); } } catch (Exception e) { e.printStackTrace(); } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * public int read() throws IOException {} * 从输入流中读取一个 8 位的字节,并把它转换为 0~255 的整数,最后返回整数。 * 如果返回 -1,则表示已经到了输入流的末尾。 */ public static void fileInputStreamByRead() { FileInputStream fis = null; try { fis = new FileInputStream("data.txt"); int num = fis.read(); while (num != -1) { // 读一个打印一个 System.out.print((char) num);/*babc717*/ num = fis.read(); } } catch (Exception e) { e.printStackTrace(); } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
案例
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class FileInputOutStreamTest { public static void main(String[] args) { FileOutputStream fos = null; FileInputStream fis = null; try { //可以复制图片、音频、视频等等 fis = new FileInputStream("1.jpg"); fos = new FileOutputStream("2.jpg"); /*fis = new FileInputStream("data.txt"); fos = new FileOutputStream("data1.txt");*/ byte[] b = new byte[1024]; int len = 0; //边读边写 while ((len = fis.read(b)) != -1) { fos.write(b, 0, len); } fos.flush(); } catch (Exception e) { e.printStackTrace(); } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
BufferedOutputStream类里有一个方法要注意
案例
import com.tjetc.IOUtils;//自己写的封装类 import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; public class BufferedOutputStreamTest { public static void main(String[] args) { FileOutputStream fos = null; BufferedOutputStream bos = null; try { fos =new FileOutputStream("data2.txt"); //BufferedOutputStream构造方法需要传入OutStream流对象 bos = new BufferedOutputStream(fos); bos.write(97);/*a*/ bos.write("abc".getBytes());/*abc*/ bos.write("0123456".getBytes(),2,5);/*23456*/ bos.flush(); } catch (IOException e) { e.printStackTrace(); } finally { IOUtils.close(bos); IOUtils.close(fos); } } } /* aabc23456 */
BufferedInputStream类里有一个方法要注意
案例
import com.tjetc.IOUtils;//自己写的封装类 import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; public class BufferedInputStreamTest { public static void main(String[] args) { FileInputStream fis = null; BufferedInputStream bis = null; try { fis = new FileInputStream("data2.txt"); //BufferedInputStream构造方法需要传入InputStream流对象 bis = new BufferedInputStream(fis); int len = 0; byte[] b = new byte[1024]; while ((len = bis.read(b)) != -1) { System.out.println(new String(b, 0, len)); } } catch (IOException e) { e.printStackTrace(); } finally { IOUtils.close(bis); IOUtils.close(fis); } } } /* aabc23456 */
案例
import com.tjetc.IOUtils; import java.io.*; public class BufferedInputOutStreamTest { public static void main(String[] args) { FileInputStream is = null; FileOutputStream os = null; BufferedOutputStream bos = null; BufferedInputStream bis = null; try { //is = new FileInputStream("1.jpg"); is = new FileInputStream("data.txt"); bis = new BufferedInputStream(is); //os = new FileOutputStream("4.jpg"); os = new FileOutputStream("data3.txt"); bos = new BufferedOutputStream(os); int len = 0; byte[] b = new byte[1024]; while ((len = bis.read(b)) != -1) { bos.write(b); bos.flush(); } } catch (Exception e) { e.printStackTrace(); } finally { IOUtils.close(bos); IOUtils.close(bis); IOUtils.close(os); IOUtils.close(is); } } } /*data3.txt文件中的内容: babc717 */
程序对应的基本输入为键盘输入,基本输出为显示器输出。
Java中,System类的in和out两个成员代表了基本输入输出的抽象
System.in:
System.in是InputStream, 标准输入流, 默认可以从键盘输入读取字节数据
import java.io.BufferedInputStream; import java.io.IOException; public class SystemInTest { public static void main(String[] args) { BufferedInputStream bis = null; System.out.println("输入数据:"); //创建BufferedInputStream对象,传入的参数是System.in的InputStream(接收键盘输入的数据) try { //System.in无需关闭 bis = new BufferedInputStream(System.in); //定义字节数组 byte[] buffer = new byte[200]; int len; //循环读取数据并打印到控制台 while ((len = bis.read(buffer)) != -1) { String s = new String(buffer, 0, len); System.out.println("您输入的数据为:" + s); } } catch (IOException e) { e.printStackTrace(); } } } /* 输入数据: aaa 您输入的数据为:aaa bb 您输入的数据为:bb c 您输入的数据为:c */
System.out是PrintStream, 标准输出流, 默认可以向控制台中输出字符和字节数据
PrintStream继承了OutputStream
import com.tjetc.IOUtils; import java.io.BufferedOutputStream; import java.io.IOException; public class SystemOutTest { public static void main(String[] args) { //创建BufferedOutputStream对象 BufferedOutputStream bos = null; try { //传入的参数System.out是PrintStream,输出控制台字符和字节 bos = new BufferedOutputStream(System.out); bos.write("SEVENTEEN".getBytes()); } catch (IOException e) { e.printStackTrace(); } finally { IOUtils.close(bos); } } } /* SEVENTEEN */
Scanner类位于java.util包中,不在java.io包中,不属于IO流
Scanner是一个工具类,主要目标是简化文本的扫描,最常使用此类获取控制台输入,Scanner获取控制台输入的步骤:
使用控制台输入创建Scanner对象
Scanner scanner=new Scanner(System.in);
调用Scanner中的nextXXX方法,获得需要的数据类型
例如:next、 nextLine、nextInt、nextByte等
import java.util.Scanner; public class ScannerTest { public static void main(String[] args) { //System.in是InputStream 字节输入流,可以读取键盘输入的数据 Scanner sc = new Scanner(System.in); System.out.println("请输入数据"); while (true) { String next = sc.next(); //"exit".equals(next) next.equals("exit") /* 如果next为null "exit".equals(next) 返回false next.equals("exit") 报空指针异常 */ if ("exit".equals(next)) { System.out.println("再见!!!"); break; } System.out.println("您输入的数据是:" + next); } } } /* 请输入数据 111 您输入的数据是:111 111 您输入的数据是:111 exit 再见!!! */
转换流:以将一个字节流转换为字符流,也可以将一个字符流转换为字节流
字节字符转换流位于java.io包
OutputStreamWriter:可以将输出的字符流转换为字节流的输出形式
字符流转换成字节流图解
案例
import com.tjetc.IOUtils; import java.io.*; public class OutputStreamWriterTest { public static void main(String[] args) { FileOutputStream fos = null; OutputStreamWriter osw = null; BufferedWriter bw = null; try { fos = new FileOutputStream("myData.txt"); osw = new OutputStreamWriter(fos, "utf-8"); bw = new BufferedWriter(osw); //BufferedWriter对象 把字符串写入流中(写入字符流 -> 转换流 -> 字节流 —> 文件中) bw.write("carat"); //flush bw.flush(); } catch (IOException e) { e.printStackTrace(); } finally { //关闭流对象 IOUtils.close(bw); IOUtils.close(osw); IOUtils.close(fos); } } } /*myData.txt文件中的内容: carat */
InputStreamReader:将输入的字节流转换为字符流输入形式。
字节流转换成字符流图解
案例
import com.tjetc.IOUtils; import java.io.*; public class SystemReaderTest { public static void main(String[] args) { //字节输入流对象 InputStream in = System.in; InputStreamReader isr = null; BufferedReader br = null; System.out.println("请输入数据:"); try { isr = new InputStreamReader(in, "utf-8"); br = new BufferedReader(isr); //BufferedReader对象循环的读取一行数据 while (true) { String s = br.readLine(); if ("exit".equals(s)) { System.out.println("ByeBye"); break; } System.out.println("您输入的数据为:" + s); } } catch (IOException e) { e.printStackTrace(); } finally { IOUtils.close(br); IOUtils.close(isr); } } } /* 请输入数据: carat 您输入的数据为:carat SEVENTEEN 您输入的数据为:SEVENTEEN exit ByeBye */
随机流(RandomAccessFile):此类的实例支持对随机访问文件的读取和写入
位于java.io包
特点
该对象即能读也能写,一个对象就搞定
该对象内部维护了一个大型 byte 数组,光标或索引在该数组任意位置读取或写入任意数据
可以通过getFilePointer方法获得光标的位置和通过seek方法设置光标位置
该对象将字节输入流和输出流进行了封装
该对象源或目的,只能文件,通过下面的构造方法就可以看出
构造方法
随机流的方法有很多
案例
import java.io.IOException; import java.io.RandomAccessFile; //在randomData.txt 写入 我在大国很安全 public class TestRandomAccessFile { public static void main(String[] args) throws IOException { //(String name/File file, String mode) ; mode 可选 "r" "w" "rw" RandomAccessFile raf = new RandomAccessFile("randomData.txt", "rw"); byte[] buffer = new byte[20]; //跳过4个汉字之后读取文件数据 raf.seek(3 * 4); //读取文件数据,把数据存到buffer,从buffer的0位置开始存储,存12个字节 raf.read(buffer, 0, 12); //把buffer中的数据转换成字符串,buffer中从0位置开始,取出12个字节 String s = new String(buffer, 0, 12); System.out.println(s);/*很安全*/ //跳过两个字节之后写入数据 raf.seek(2 * 3); //写数据 注意:写的数据会覆盖对应位置的原数据 raf.write("中".getBytes()); } } /*randomData文件中的内容: 我在中国很安全 */
字节数组流:提供了针对于字符数组 byte [] 的标准的IO操作方式
位于java.io包
ByteArrayInputStream 和 ByteArrayOutputStream
ByteArrayInputStream将会给一个byte buf[] 提供标准的IO操作方式
ByteArrayOutputStream将数据写入到内部的字节数组中
案例
import java.io.*; public class TestByteArrayOutputAndInputStream { public static void main(String[] args) { byte[] buffer = getBuffer(); printBuffer(buffer); } private static byte[] getBuffer() { byte[] buffer = null; ByteArrayOutputStream baos = null; BufferedOutputStream bos = null; try { baos = new ByteArrayOutputStream(); bos = new BufferedOutputStream(baos); //写入数据到ByteArrayOutputStream对象baos中(内存中) bos.write("SEVENTEEN".getBytes()); bos.flush(); //baos转换成数据赋值给数据buffer存储中 buffer = baos.toByteArray(); /*public synchronized byte toByteArray()[] { return Arrays.copyOf(buf, count); }*/ } catch (IOException e) { e.printStackTrace(); } finally { try { if (bos != null) { bos.close(); } if (baos != null) { bos.close(); } } catch (IOException e) { e.printStackTrace(); } } return buffer;/*buffer:{83,69,86,69,78,84,69,69,78}*/ } private static void printBuffer(byte[] buffer){ ByteArrayInputStream bais = null; BufferedInputStream bis =null; byte[] b =new byte[buffer.length]; try{ bais = new ByteArrayInputStream(buffer); bis = new BufferedInputStream(bais); //读取数据到b数组中 bis.read(b); } catch (IOException e) { e.printStackTrace(); }finally { try { bis.close(); bais.close(); } catch (IOException e) { e.printStackTrace(); } } System.out.println(new String(b));/*SEVENTEEN*/ } }