文件
文件在程序中是以流的形式来操作的
java程序(内存)----->文件 输入流
文件-------------->java 输出流
创建文件
文件类的构造方法
-
new File("文件路径")
String file="d:\\news1.text"; File file1 = new File(file);
-
new File(父文件 File,子文件 String)
File parentFile=new File("d:\\"); String fileName="news2.text"; File newfile=new File(parentFile,fileName); try { newfile.createNewFile();只有执行了createNewFile操作,才会在磁盘里创建文件 System.out.println("创建成功"); } catch (IOException e) { throw new RuntimeException(e); }
-
New File(String 父目录,String 子路径)
String parent="d:\\"; String haizi="newtext03"; File newfile=new File(parent,haizi); try { newfile.createNewFile(); } catch (IOException e) { throw new RuntimeException(e); }
获取文件的相关信息
在java编程中,目录也被当成文件
调用文件的方法
【1】length是根据字节去计算的
【2】getAbsolutePath是路径
目录的操作和文件删除
IO流的原理和流的分类
流的分类
-
按照操作数据单位的不同:字节流 (适用于二进制文件) 字符流(按字符) 文本文件
-
按照数据的流向不同分为:输入流 输出流
-
按照流的角色的不同分为:节点流,处理流/包装流
InputStream
【1】是所有类字节输入流的超类(被子类继承的类)
【2】FileInputStream:文件输入流(文件有中文会出现乱码)
String filePath="d:\\news1.text"; int readData=0; FileInputStream fileInputStream=null; try { fileInputStream =new FileInputStream(filePath); while((readData=fileInputStream.read())!=-1){ System.out.print((char) readData); } } catch (IOException e) { e.printStackTrace(); } finally{ try { fileInputStream.close(); } catch (IOException e) { throw new RuntimeException(e); } }
上述单个字节读取效率较低 使用read(byte[] b)解决
String filePath="d:\\news1.text"; byte[] buf=new byte[8]; int readlen=0; FileInputStream fileInputStream=null; try { fileInputStream =new FileInputStream(filePath); while((readlen=fileInputStream.read(buf))!=-1){ System.out.print(new String(buf,0,readlen)); } } catch (IOException e) { e.printStackTrace(); } finally{ try { fileInputStream.close(); } catch (IOException e) { throw new RuntimeException(e); } }
OutputStream
【1】fileOutStream
使用FileOutStream将数据写到文件上,如果该文件不存在,则创建该文件
fileoutputStream对象的write方法
String filePath="d:\\news1.text"; FileOutputStream fileOutputStream=null; try { fileOutputStream=new FileOutputStream(filePath); fileOutputStream.write('h'); } catch (IOException e) { throw new RuntimeException(e); }finally{ try { fileOutputStream.close(); } catch (IOException e) { throw new RuntimeException(e); } } }
在该方法操作下会覆盖原文本的内容 fileOutputStream.write('h');而且适用于单个字符
第二种方法为多个字符
首先要将修改的内容放到一个字符串内,在用字符串的getbytes()方法去转成字节数组 void write(Byte [])
String filePath="d:\\news1.text"; FileOutputStream fileOutputStream=null; try { String s="welcome to my world"; fileOutputStream=new FileOutputStream(filePath); fileOutputStream.write(s.getBytes()); } catch (IOException e) { throw new RuntimeException(e); }finally{ try { fileOutputStream.close(); } catch (IOException e) { throw new RuntimeException(e); } }
这一个为可以确定长度
String filePath="d:\\news1.text"; FileOutputStream fileOutputStream=null; try { String s="welcoto my world"; fileOutputStream=new FileOutputStream(filePath); fileOutputStream.write(s.getBytes(),0,s.length()-7); } catch (IOException e) { throw new RuntimeException(e); }finally{ try { fileOutputStream.close(); } catch (IOException e) { throw new RuntimeException(e); } }
在文档内容后面添加内容,而不是覆盖,在FileOutputStream构造函数的添加
fileOutputStream=new FileOutputStream(filePath,true);
字节流拷贝图片
String filepath="c:\\Users\\范文豪\\Pictures\\Screenshots\\OIP-C.jpg"; String lastpath="d:\\ OIP-C.jpg"; FileInputStream fileInputStream=null; FileOutputStream fileOutputStream=null; try { int readlen=0; fileInputStream=new FileInputStream(filepath); fileOutputStream=new FileOutputStream(lastpath); byte[] buf=new byte[1024]; while((readlen=fileInputStream.read(buf))!=-1){ fileOutputStream.write(buf,0,readlen); } } catch (IOException e) { throw new RuntimeException(e); }finally{ try { if(fileInputStream!=null){ fileInputStream.close(); } if(fileOutputStream!=null){ fileOutputStream.close(); } } catch (IOException e) { throw new RuntimeException(e); } finally { } }
FileReader 字符流
由图可知fileReader的父类为InputStreamReader
FileReader
是文件字符输入流,用于读取文本文件。该类的父类为 InputStreamReader
,它是字节流和字符流的桥梁,它读取字节流并使用指定的字符集解码为字符。InputStreamReader
的父类便是字符输入流 Reader
了。
FileReader的构造方法FileReader
类有三个构造函数,它们使用默认的字符集来读取文本文件。如果想要指定字符集,需要借助其父类 InputStreamReader
。
FileReader的构造函数
FileReader(String fileName)
通过文件路径名,创建文件字符输入流
FileReader
实例。
String filePath="d:\\news1.text"; FileReader fileReader = null;//单个字符读取 int data=0; try { fileReader= new FileReader(filePath); while((data=fileReader.read())!=-1){ System.out.print((char) data); } } catch (IOException e) { throw new RuntimeException(e); }finally { if(fileReader!=null){ try { fileReader.close(); } catch (IOException e) { throw new RuntimeException(e); } } }
FileReader(File file)
通过文件
File
实例,创建文件字符输入流FileReader
实例。
FileReader(FileDescriptor fd)
通过文件描述符
FileDescriptor
实例,创建文件字符输入流FileReader
实例。
常用方法
1.read()方法只读取一个字符
fileReader= new FileReader(filePath); while((data=fileReader.read())!=-1){ System.out.print((char) data); }
2.read(char [],int ,int)方法每次读取多个字符
String filePath="d:\\news1.text"; char [] buf =new char[8]; FileReader fileReader = null;//单个字符读取 int data=0; try { fileReader= new FileReader(filePath); while((data=fileReader.read(buf))!=-1){ System.out.print((new String(buf,0,data))); } }
FileWriter 字符流
常用方法:
-
构造方法 new FileWriter(File/String) :覆盖模式,相当于流的指针在首端
-
构造方法 new FileWriter(File/String,true): 追加模式,相当于流的指针在末端
-
write(int):写入单个字符
-
write(char[]):写入指定数组
-
write(char [],off,len)写入指定数组的指定部分
-
write(String) 写入指定字符串
String filePath="d:\\news1.text"; FileWriter fileWriter=null; String s="trust youself"; try { fileWriter=new FileWriter(filePath); fileWriter.write(s); } catch (IOException e) { throw new RuntimeException(e); } finally{ if(fileWriter!=null){ try { fileWriter.flush(); } catch (IOException e) { throw new RuntimeException(e); } }
-
write(String,off,len)写入指定字符串的指定部分
节点流和处理流的区别
节点流和处理流的区别和联系
节点流是底层流/低级流,直接跟数据源连接。
处理流(包装流)包装节点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入和输出。
处理流对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相连接。
处理流的功能体现
性能的提高:主要以增加缓冲的方式来提高输入输出的效率。
操作的便捷:处理流可能提供了一系列便捷的方法来一次性输入和输出大批量的数据,使用更加灵活方便。
原文链接:https://blog.csdn.net/weixin_46421722/article/details/122764143
BufferReader 和BufferWirter
读取文件
public class BufferedReader extends Reader {// 继承了Reader类,而且定义了Reader类的属性 private Reader in;
String filePath="d:\\news1.text"; BufferedReader bufferedReader = null; String readlen; bufferedReader = new BufferedReader(new FileReader(filePath)); while((readlen=bufferedReader.readLine())!=null){//包装成BufferReader,可以使用更高效的读取方法 System.out.print(readlen); } bufferedReader.close();//关闭外层流
写入文件
String filePath="d:\\news1.text"; BufferedWriter bufferedWriter=new BufferedWriter(new FileWriter(filePath)); bufferedWriter.write("hello,喊顺平"); bufferedWriter.close();
利用BufferReader 和BufferWriter拷贝文件,但是不能读取二进制文件,拷贝过去已经损坏了
BufferInputStream
BufferedOutputStream
使用 BufferInputStream, BufferedOutputStream 可以拷贝二进制文件(ASCII码,Unicode编码)和文本文件(数据在物理上的存储方式是二进制的,即由0/1字符串构成),但是编码方式不一样,一个是基于字符编码(文本文件),ASCII码,Unicode编码,另一个是基于值编码(二进制文件)
https://blog.csdn.net/simmel_92/article/details/89064977
拷贝文件
public static void main(String[] args) throws Exception { String filepath="d:\\a.jpg"; String lastpath="d:\\web picture\\OI.jpg"; BufferedInputStream bufferedInputStream=new BufferedInputStream(new FileInputStream(filepath)); BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(new FileOutputStream(lastpath)); int readlen=0; byte by[]=new byte[1024]; while((readlen=bufferedInputStream.read(by))!=-1){ bufferedOutputStream.write(by,0,readlen); } bufferedInputStream.close(); bufferedOutputStream.close(); }}
对象处理流 (保存值和数据类型)
暂时无法在飞书文档外展示此内容
https://blog.csdn.net/qq_44543508/article/details/103232007
序列化
public static void main(String[] args) throws Exception { String filePath="d:\\data.dat"; ObjectOutputStream objectOutputStream=new ObjectOutputStream(new FileOutputStream(filePath)); objectOutputStream.write(100); //int-Integer objectOutputStream.writeBoolean(true);//boolean-Boolean objectOutputStream.writeChar('a'); objectOutputStream.writeUTF("fdghjk");//String 本身就标记接口 其实都是包装的过程 objectOutputStream.writeObject(new Dog("p",90));//如果没有继承seSerializable ,会出现异常的 ObjectOutputStream.close(); }} class Dog implements Serializable{ String name; int age; public Dog(String name, int age) { this.name = name; this.age = age; } }
反序列化
1。反序列化的顺序和序列化的顺序要保持一致,否则会出现异常
而且最后一行readObject必须先运行上面的程序(输入程序),才能生成Dog类,否则会报错
String filePath = "d:\\data.dat"; ObjectInputStream objectInputStream=new ObjectInputStream(new FileInputStream(filePath)); System.out.println(objectInputStream.readInt()); System.out.println(objectInputStream.readBoolean()); System.out.println(objectInputStream.readChar()); System.out.println(objectInputStream.readUTF()); System.out.println(objectInputStream.readObject().getClass());
如果想调用dog的特殊方法,需要向下转型因为 objectInputStream.readObject()这个对象是Object
Object dg= objectInputStream.readObject(); Dog dg1=(Dog) dg;//向下转型,才可以调用该类特有方法 dg1.t(); System.out.println(dg1.toString());
对象处理流细节
1.读写顺序要一致
2.要求实现序列化或者反序列化,需要实现Serializable接口
3】如果写入序列号时,修改类时系统只是原先类的修改。
private static final long serialVersionUID=1l;
serialVersionUID适用于Java的序列化机制。简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常,即是InvalidCastException,在开发中有时候可写可不写,建议最好还是写上比较好。
标准输入输出流:
System in编译类型 public static final InputStream in = null; 标准输入
运行类型 BufferedInputStream
System out编译类型 public static final PrintStream out = null;
运行类型 PrintStream
转换流:字符流(因为编码方式的不同)
InputStreamReader
主要在乱码时,用第三个构造函数,Charest代表编码方式
InputStreamReader inputStreamReader=new InputStreamReader(new FileInputStream(filePath),"utf-8"); BufferedReader io=new BufferedReader(inputStreamReader); String s= io.readLine(); System.out.println(s); io.close();
OutputStreamReader
String filePath="d:\\news1.text"; OutputStreamWriter outputStream=new OutputStreamWriter(new FileOutputStream(filePath),"gbk"); outputStream.write("继续努力"); outputStream.close();
打印流:只有输出流没有输入流
PrintStream:字节流
PrintStream printStream=System.out; printStream.print("hrrloooo");//在默认位置,输出的位置是显示器 // public void print(String s) { // write(String.valueOf(s)); // } printStream.close();
因为print方法 本质为write方法,所以也可以使用write方法
printStream.write("fhjk".getBytes());
可以修改路径/设备
System.setOut(new PrintStream("d:\\news.txt")); System.out.println("cfghjksjvhbx");
PrintWriter:字符流
PrintWriter printWriter=new PrintWriter(System.out); printWriter.println("fgshjkls"); printWriter.flush();
可以修改路径/设备
PrintWriter printWriter=new PrintWriter(new FileWriter("d:\\news1.text")); printWriter.println("fgshjkls"); printWriter.flush();
properties类
因为properties的父类就是hashtable,所以他的底层逻辑就是hashtable
1.Properties类是什么?
Properties(Java.util.Properties),该类主要用于读取Java的配置文件,不同的编程语言有自己所支持的配置文件,配置文件中很多变量是经常改变的,为了方便用户的配置,能让用户够脱离程序本身去修改相关的变量设置。就像在Java中,其配置文件常为.properties文件,是以键值对的形式进行参数配置的。
2.读取properties文件
BufferedReader bufferedReader=new BufferedReader(new FileReader("src\\mysql.properties")); String line=""; while((line=bufferedReader.readLine())!=null){ System.out.println(line); }
3.properties创建文件 setProperty(String key, String value)
Properties properties=new Properties(); properties.setProperty("cahrest","utf-8");// k-v键值对 properties.setProperty("usr","9000"); //将k-v键值对存储 properties.store(new FileOutputStream("src\\a.properties"),null); //public void store(OutputStream out, String comments) 的作用如下,相当于注释
4.修改键值对()重复一遍上述的操作