java之IO流(一)
来源:互联网 发布:企业统一认证 知乎 编辑:程序博客网 时间:2024/06/06 00:31
**IO流java中的IO流按照数据类型分为两种:字节流(用得最多)和字符流(多用于处理文档)。
IO流按流向分为:输入流,输出流。**
字节流的抽象基类:InputStream,OutputStream
字符流的抽象基类:Reader,Writer
1.字符流Writer和Reader
1.1在硬盘上创建一个文件并且写入文字数据
static void createFileAndWrite(){ try { //FileWriter是Writer的子类。如果文件不存在会在D盘下创建文件。 Writer writer=new FileWriter("D:/test.txt"); //写入字符串数据 writer.write("zhangsan"); //写入之后,数据是在内存中,必须调用flush()方法刷新,将数据从内存写入文件 writer.flush(); //关闭资源,此方法执行之前,会自动调用flush()方法刷新数据,将内存中的数据写入到文件后再关闭。 writer.close(); } catch (IOException e) { System.err.println(e.toString()); } }
在D盘创建文件,还可以写成:
Writer writer=new FileWriter("D:\\test2.txt");
因为“\”在java中表示转义字符,所以用”\”来表示文件层次。
Writer writer=new FileWriter("D:/test2.txt",true);
表示在test2.txt文件后面追加数据,而不会覆盖test2.txt以前就存在的数据。
1.2 FileReader读取硬盘文档上的数据。
1.2.1 read()方法(不常用)
FileReader 的read()方法返回的是所读到字符的ASCII码。如果读到了文件的末尾,则会返回-1.所以以-1作为循环条件。
代码:
static void readFile(){ try { Reader reader=new FileReader("D:/test2.txt"); int count=0; while((count=reader.read())!=-1){ //将ASCII码转化为字符 System.out.print((char)count); } reder.close(); } catch (IOException e) { e.printStackTrace(); } }
1.2.2 read(char[])方法
FileReader的read(char[])是将文件里面的数据读入到char[]缓冲区里面。返回的是每次读取到的个数。如果已经到文件
末尾,则返回-1.read(char[])方法逐位覆盖char缓冲区里面的数据。每执行一次此方法,都会覆盖掉char缓冲区里面原有的数据。
代码:
static void readFile2(){ try { Reader reader=new FileReader("D:/test2.txt"); char[]buf=new char[1024]; int num=0; while((num=reader.read(buf))!=-1){ System.out.print(new String(buf,0,num)); } reder.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
1.3复制文件(将文件从一个磁盘复制到另一个磁盘)。
思路:
- 创建写对象和读对象。构造方法为文件路径。
- 创建字符数组作为缓冲区。
- 数据读到缓冲区以后,马上写入指定文件,完成文件复制。
- 关闭资源。
代码:
static void copyFile(){ FileReader fileReader=null; FileWriter fileWriter=null; try { fileReader=new FileReader("D:/code.java"); fileWriter=new FileWriter("E:/code.java"); //定义缓冲区 char[]buf=new char[1024]; int len=0; while((len=fileReader.read(buf))!=-1){ fileWriter.write(buf, 0, len);//写入到新文件中 System.out.print(new String(buf,0,len));//数据打印到控制台 } } catch (IOException e) { throw new RuntimeException("出错了"); } //关闭资源 finally{ if(fileReader!=null) try { fileReader.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(fileWriter!=null) try { fileWriter.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
2.字符流缓冲区
字符流缓冲区对应的类有BufferedWriter和BufferedReader。
缓冲区的出现是为了提高流的操作效率出现的。字符流缓冲区和使用数组作为缓冲区原理基本一致。先将数据读或写到缓冲区(内存)中。当缓冲区满了的时候,在硬盘上进行读写操作。避免了频繁读写硬盘,提高了效率。
因此在创建缓冲区之前,必须先要有流对象。
2.1BufferedWriter向硬盘写数据
代码:
static void bufferTest1() throws IOException{ //创建FileWriter对象 FileWriter fileWriter=new FileWriter("D:/test.txt"); //创建BufferedWriter对象,以FileWriter对象作为构造参数 BufferedWriter bufferedWriter=new BufferedWriter(fileWriter); //写一个Hello BufferedWriter就换行 for(int i=0;i<6;i++){ bufferedWriter.write("Hello BufferedWriter"+i); bufferedWriter.newLine();//换行 bufferedWriter.flush();//必须刷新,将数据从内存写到硬盘上 } bufferedWriter.close();//关闭资源,关闭之前,会刷新一次。 }
2.1 BufferedReader读硬盘数据
BufferedWriter除了拥有FileReader的两个重载的read方法外,还可以读取一行文本。简化了程序,提高了效率。
readLine()方法读取的是每行的有效数据,并不包含每行结尾处的换行符。
代码:
static void bufferRead1()throws IOException{ //创建FileReader对象 FileReader fileReader=new FileReader("D:/test.txt"); //创建BufferedReader对象,以FileReader对象作为构造参数 BufferedReader bufferedReader=new BufferedReader(fileReader); //BufferedReader可以读取一行文本,该方法返回String。如果读到末尾,返回null。 String dataString=null; while((dataString=bufferedReader.readLine())!=null){ System.out.println(dataString); } bufferedReader.close();//读完关闭资源 }
2.3 Buffered实现文本文档拷贝
static void bufferCopy()throws IOException{ //创建Buffered读写对象 BufferedReader bufferedReader=new BufferedReader(new FileReader("D:/code.java")); BufferedWriter bufferedWriter=new BufferedWriter(new FileWriter("E:/code2.java")); String dataString=null; while((dataString=bufferedReader.readLine())!=null){ bufferedWriter.write(dataString); System.out.println(dataString); bufferedWriter.newLine();//写完一行,就换行,因为readLine只读取有效数据,不包含换行符 bufferedWriter.flush();//写完一行,就刷新一次 } //关闭资源。 bufferedReader.close(); bufferedWriter.close(); }
3. 装饰类
新建一个类,将需要装饰的类作为该类的构造方法参数。该类中的方法实现调用装饰类中的方法,但进行加强。
例如BufferedReader类中的readLine()方法就是基于FileReader的read()方法来实现的。
装饰类的构造方法参数里面的一定有被装饰类。
class MyBufferedReader extends Reader{ private FileReader fileReader; public MyBufferedReader(FileReader fileReader){ this.fileReader=fileReader; } public void myReadLine(){ //调用FileReader的read()方法实现具体的readLine方法 } //...还需要覆盖Reader中的抽象方法,此处省略}
4. 其他
**因为BufferedReader和BufferedWriter对缓冲区进行了封装,不需要char数组,因此使用相比
FileReader和FileWriter方便一些。**
5. 字节流
字节流的抽象基类:InputStream,OutputStream
字节流的缓冲区是字节数组
5.1 字节流写文件
代码:
static void outputStreamTest1 ()throws IOException{ //会创建一个文件 FileOutputStream outputStream=new FileOutputStream("D:/test2.txt"); String string="锄禾日当午" +"\r\n"+"汗滴禾下土"; outputStream.write(string.getBytes());//必须是字节数组 outputStream.close(); }
5.2 字节流读文件
代码:
static void inputStreamTest1()throws IOException{ FileInputStream inputStream=new FileInputStream("D:/test2.txt"); byte[] bytes=new byte[1024];//创建字节缓冲区 int len=0; //如果读到末尾,则返回-1 while((len=inputStream.read(bytes))!=-1){ System.out.println(new String(bytes,0,len)); } inputStream.close(); }
第二种字节流读文件方式(不建议使用)
代码:
/** * 因为缓冲区的大小和文件一样,所以不用循环读数据,直接从缓冲区读数据即可。 * @throws IOException */ static void inputStreamTest2()throws IOException{ FileInputStream inputStream=new FileInputStream("D:/test2.txt"); //inputStream.available()返回的是文件可读的字节数 byte[] bytes=new byte[inputStream.available()];//创建字节缓冲区,大小等于文件按的大小 inputStream.read(bytes); System.out.println(new String(bytes)); inputStream.close(); }
如果文件太大,那么创建缓冲区的时候会造成虚拟机内存耗尽,不安全。
5.3 字节流实现文件复制
代码:
/** * 和使用字符流复制文档文件操作基本一致: * 1,创建读和写的字节流对象。 * 2,创建字节缓冲区。 * 3,从数据读到缓冲区里面。 * 4,从缓冲区里将数据写入硬盘。 * @throws IOException */ static void streamCopyPicture()throws IOException{ FileInputStream inputStream=new FileInputStream("D:/view.jpg"); FileOutputStream outputStream=new FileOutputStream("E:/copy.jpg"); byte[] buffer=new byte[1024]; int len=0; while((len=inputStream.read(buffer))!=-1){ outputStream.write(buffer,0,len); } inputStream.close(); outputStream.close(); }
5.4 字节流缓冲区实现文件拷贝
代码:
/** * 字节流缓冲区实现文件拷贝 * @throws IOException */ static void bufferedCopy()throws IOException{ BufferedInputStream inputStream=new BufferedInputStream(new FileInputStream("D:/view.jpg")); BufferedOutputStream outputStream=new BufferedOutputStream(new FileOutputStream("E:/copy2.jpg")); int ch=0; //inputStream.read()读取到的是一个字节的数据 while((ch=inputStream.read())!=-1){ outputStream.write(ch); } inputStream.close(); outputStream.close(); }
用法和字符缓冲区的用法基本一致。不过inputStream.read()读取到的是一个字节。
6.转换流
如果需要指定编码方式,那么就需要用到转换流,转换流可以指定编码方式。
6.1 InputStreamReader
从键盘读取数据,如果输入为over,则结束。
//转换流InputStreamReader static void keyboardIn()throws IOException{ //inputStream从键盘录入 InputStream inputStream=System.in; //InputStreamReader是Reader子类,转化流:将字节流转化为字符流 InputStreamReader reader=new InputStreamReader(inputStream); //创建字符流缓冲区对象,用这个就不用创建字符数组作为缓冲区了 BufferedReader bufferedReader=new BufferedReader(reader); String string=null; //每次只读取一行 while((string=bufferedReader.readLine())!=null){ if(string.equals("over")){ break; } System.out.println(string); } }
6.2 OutputStreamWriter
OutputStreamWriter是Writer的子类。
以OutputStream作为构造参数。
模拟控制台输出:
{ //System.out控制台输出返回OutputStream OutputStream outputStream=System.out; //转化流,将字节流转化为字符流 OutputStreamWriter outputStreamWriter=new OutputStreamWriter(outputStream); //使用bufferd缓冲区 BufferedWriter bufferedWriter=new BufferedWriter(outputStreamWriter); //写入一个字符串 bufferedWriter.write("zhang san"); //写入一个回车换行 bufferedWriter.newLine(); //关闭资源 bufferedWriter.close(); }
7.打印流
//获取系统信息。Properties properties=System.getProperties();properties.list(new PrintStream("D:/test3.txt"));System.out.println(properties);
8. 文件对象File
8.1 文件分隔符
windows和linux下文件分隔符不同,java提供了跨平台的操作来获取文件分隔符。
String string=File.separator;
8.2 常用方法
1,创建文件:
boolean createNewFile(); 在指定位置创建文件,如果文件已经存在,则不创建,返回false。
创建成功,返回true。
File file =new File(“file.txt”);
file.createNewFile();//若创建成功,则返回true。若存在则不创建。
创建文件夹:
File mkdir=new File(“test”);
mkdir.mkdir();创建一个test文件夹(文件目录)。此方法只能创建一级目录。
File mkdirs=new File(“test\movies”);
mkdirs.mkdirs()
创建多级文件夹,test文件夹下还有movies文件夹。
2,删除文件:
boolean delete();但是如果文件在进行读写操作,删除失败,返回false。
void deleteOnExit();在程序退出时删除指定文件。
3,判断:
boolean canExecute() ; 文件是否能执行。
canRead():是否可读。
canWrite();是否可写。
boolean exists() ;文件是否存在。
boolean isDirectory() :判断当前 抽象路径File是不是文件夹(目录)
boolean isFile() :判断当前 抽象路径File是不是标准文件。
4.获取信息:
String getAbsolutePath() :返回此抽象路径名的绝对路径名形式
long length() :返回由此抽象路径名表示的文件的长度。
String getPath() :将此抽象路径名转换为一个路径名字符串。
boolean renameTo(File dest) :重新命名此抽象路径名表示的文件。
8.3 递归列出指定文件下所有的目录和文件
//列出指定文件下的文件和文件夹,包含子目录中的内容 static void showDir(File file){ System.out.println(file); //列出该文件下所有的文件夹和文件 File[]files=file.listFiles(); for(int x=0;x<files.length;x++){//遍历 //如果列出的文件是文件夹,那么调用showDir()方法,继续列出其下面的文件和文件夹 if(files[x].isDirectory()){ showDir(files[x]); }else { System.out.println(files[x]); } } }
- 递归必须要有跳出的条件
- 递归次数不能太多,否则会造成内存溢出。因为每调用一次方法,都会重新开辟一块内存。
- 9. java配置文件与Properties
**Properties是Hashtable的子类,具备map集合的特点,而且存储的键值对都是字符串。
它是集合中和IO技术相结合的集合容器。用来键值对形式的配置文件。**
代码1:
static void propertiesTest1(){ //创建对象 Properties properties=new Properties(); //设置键值对 properties.setProperty("name", "liang"); properties.setProperty("age", "28"); properties.setProperty("country", "China"); //得到所有字符串类型的键 Set<String>set=properties.stringPropertyNames(); //根据键对Properties进行遍历 for(String string:set){ System.out.println(string+"--"+properties.get(string)); } }
//输出结果age--28name--liangcountry--China
创建配置文件并用Properties读取和修改:
代码2:
/** * Properties和IO流进行关联必须创建相关的IO流对象。 * @throws IOException */ static void propertiesTest2()throws IOException{ //创建读取的IO流对象,info.txt是配置文件。 FileInputStream fileInputStream=new FileInputStream("D:/info.txt"); Properties properties=new Properties(); //加载流对象,除了InputStream,还可以是Reader。 properties.load(fileInputStream); //添加一条配置数据 properties.setProperty("hobby", "eating"); //修改配置数据后,必须使用写入流对象将修改后的数据保存到文件中。 FileOutputStream fileOutputStream=new FileOutputStream("D:/info.txt"); //将修改的信息保存到文件中,第二个参数是说明信息。除了可以使用OutputStream,还可以使用Writer。 properties.store(fileOutputStream, "第一次修改"); Set<String>set=properties.stringPropertyNames(); //根据键对Properties进行遍历 for(String string:set){ System.out.println(string+"--"+properties.get(string)); } //关闭流资源 fileInputStream.close(); fileOutputStream.close(); }
10. 序列流
序列流,可以将多个文件中的内容合并成一个文件
/** * 序列流,可以将多个文件中的内容合并成一个文件 * @throws IOException */ static void sequenceStreamTest() throws IOException{ Vector<FileInputStream>vector=new Vector<>(); //三个文件,创建三个字节输入流对象。 FileInputStream inputStream1=new FileInputStream("D:/1.txt"); FileInputStream inputStream2=new FileInputStream("D:/2.txt"); FileInputStream inputStream3=new FileInputStream("D:/3.txt"); vector.add(inputStream1); vector.add(inputStream2); vector.add(inputStream3); Enumeration<FileInputStream> enumeration=vector.elements(); //构造方法参数是Enumeration对象,所以需要用到Vector。 SequenceInputStream sequenceInputStream=new SequenceInputStream(enumeration); //创建输出流,将合并好的流进行输出。 FileOutputStream outputStream=new FileOutputStream("D:/4.txt"); //进行读写操作。 byte[] bytes=new byte[1024]; int len=0; while((len=sequenceInputStream.read(bytes))!=-1){ outputStream.write(bytes,0,len); } //关闭资源 sequenceInputStream.close(); outputStream.close(); }
- java之IO流详解(一)
- Java回炉之IO流(一)
- Java之IO流概述(一)
- java之IO流(一)
- Java之IO(一)
- 黑马程序员---java之IO流(一)
- 黑马程序员-Java学习笔记之IO流(一)
- java中的IO流之File类(一)
- java学习笔记之IO流总结(一)
- java--------学习之《IO流》一
- 黑马程序员 java之io流一
- Java基础知识之IO流(一)
- java基础巩固之IO(一)
- Java初学之IO(一)
- JAVA基础之IO(一、IO结构)
- java------IO流(一)
- JAVA IO流(一)
- java IO流(一)
- 安装SDKMAN(The Software Development Kit Manager)
- Java 线程回调
- 关联和依赖的区别
- double类型精度计算
- 如何在ASP.Net创建各种3D图表
- java之IO流(一)
- SQL 事务隔离级别
- Java Lambda(2)
- 背景模型
- 题目1167:数组排序
- java中volatile关键字的含义
- 2017-1期
- 数字货币备份教程
- 逐行扫描和隔行扫描的区别,原理