dw如何做商业网站网站建设 展滔科技大厦
- 作者: 多梦笔记
- 时间: 2026年02月16日 12:08
当前位置: 首页 > news >正文
dw如何做商业网站,网站建设 展滔科技大厦,济源网站制作,集成装修全屋定制一、File类的使用
1.1 概述 File 类以及本章中的各种流都定义在 java.io 包下 一个File对象代表硬盘或网络中可能存在的一个文件或文件夹#xff08;文件目录#xff09; File 能新建、删除、重命名 文件和目录#xff0c;但 File不能访问文件内容本身。如果我们想要访问…一、File类的使用
1.1 概述 File 类以及本章中的各种流都定义在 java.io 包下 一个File对象代表硬盘或网络中可能存在的一个文件或文件夹文件目录 File 能新建、删除、重命名 文件和目录但 File不能访问文件内容本身。如果我们想要访问文件内容本身就需要使用 输入/输出流 将 File 对象作为参数传递给流的构造器 在Java程序中表示一个真实存在的文件或目录用File对象但定义的File对象不一定对应真实存在的文件或目录file not found
1.2 构造器
public File(String pathname): 以pathname为路径创建File对象 pathname是绝对路径或相对路径都可以如果为相对路径则默认的当前路径在系统属性 user.dir 中存储 public File(String parent, String child): 以parent为父路径child为子路径创建File对象 【将父子路径拼接到一起就是个完整路径】public File(File parent, String child): 根据一个父 File对象和子文件路径创建File对象【根据一个文件/目录的地址child拼接新地址】 简述一下绝对路径和相对路径的概念 绝对路径属于一个从盘符开始的完整路径相对路径相对于项目目录的路径 IDEA中main中的文件的相对路径是相对于当前工程IDEA中单元测试方法中的文件的相对路径是相对于当前module【模块】 代码演示 package com.zwh.shangguigu.fileandio;import java.io.File;/*** author Bonbons* version 1.0*/
public class FileObjectTest {public static void main(String[] args) {//通过pathname创建File对象String path D:\dataBase;File file1 new File(path);//通过父路径子路径创建File对象String parent C:\aaa;String child bbb.txt;File file2 new File(parent, child);//通过File对象子路径创建File对象File parentDir new File(d:\aaa);String childFile bbb.txt;File file3 new File(parentDir, childFile);//我们来打印一些File对象相关的信息System.out.println(file1 file1);System.out.println(文件/目录的名称: file2.getName());System.out.println(文件/目录的构造路径名: file3.getPath());System.out.println(文件/目录的绝对路径名: file1.getAbsoluteFile());System.out.println(文件/目录的父目录名: file2.getParent());}
}总结 无论该路径下是否存在文件或者目录都不影响File对象的创建 window的路径分隔符使用“\”而Java程序中的“\”表示转义字符所以在Windows中表示路径需要使用\或/,或者用File.separator常量值表示 File file2 new File(“d:” File.separator “atguigu” File.separator “info.txt”);当构造路径是绝对路径时那么getPath和getAbsolutePath结果一样 当构造路径是相对路径时那么getAbsolutePath的路径 user.dir的路径 构造路径
1.3 常用方法 1、获取文件和目录的基本信息
public String getName(): 获取名称public String getPath(): 获取路径 public String getAbsolutePath(): 获取绝对路径 public File getAbsoluteFile(): 获取绝对路径表示的文件public String getParent(): 获取上层目录路径没有则返回nullpublic long length(): 获取文件不能是目录的长度(字节数)public long lastModified(): 获取最后一次的修改时间毫秒值 有一个值得我们注意的 如果File对象代表的文件或目录存在则File对象实例初始化时就会用硬盘中对应文件或目录的属性信息例如时间、类型等为File对象的属性赋值否则除了路径和名称File对象的其他属性将会保留默认值 【可以看下图辅助理解】 我来编写代码具体演示一下file1存在、file2不存在 package com.zwh.shangguigu.fileandio;import java.io.File;/*** author Bonbons* version 1.0/
public class FileInfoMethod {public static void main(String[] args) {//存在的文件File file1 new File(d:/小红书Java后端开发.png);System.out.println(文件构造路径: file1.getPath());System.out.println(文件名称: file1.getName());System.out.println(文件长度: file1.length() 字节);System.out.println(文件最后修改时间: file1.lastModified());System.out.println();//虚构的文件File file2 new File(d: File.separator aaa.txt);System.out.println(文件构造路径: file2.getPath());System.out.println(文件名称: file2.getName());System.out.println(文件长度: file2.length() 字节);System.out.println(文件最后修改时间: file2.lastModified());}
}2、列出目录的下一级
public String [] list(): 返回一个String数组表示该File目录中的所有子文件或目录public File[] listFiles(): 返回一个File数组表示该File目录中的所有的子文件或目录 区别就在于返回的一个是字符串数组、一个是文件数组 字符串数组可以用于一些特征信息的提取文件数组可以用于进一步加工成新的File对象 代码演示一下 package com.zwh.shangguigu.fileandio_;import java.io.File;/** author Bonbons* version 1.0/
public class DirListFiles {public static void main(String[] args) {File file1 new File(d:\cfhd);File file2 new File(d:/DataBase);//采用两种方式获取目录的子文件或子目录名并打印输出String [] list file1.list();File [] listFiles file2.listFiles();for(String child : list){System.out.print(child );}System.out.println();for (File file : listFiles){System.out.print(file );}}
}3、File 类的重命名功能
public boolean renameTo(File dest): 把文件重命名为指定的文件路径 代码测试失败了 4、判断功能的方法
public boolean exists(): 判断File表示的文件/目录是否真实存在public boolean isDirectory: 判断File表示的是不是目录public boolean isFile: 判断File表示的是不是文件public boolean canRead(): 判断是否可读public boolean canWrite(): 判断是否可写public boolean isHidden(): 判断是否隐藏 代码演示 package com.zwh.shangguigu.fileandio_;import java.io.File;/** author Bonbons* version 1.0/
public class DirListFiles {public static void main(String[] args) {File file1 new File(d:\WeGame);System.out.println(d:/WeGame 是否存在: file1.exists());System.out.println(d:\aaa 是否存在: new File(d:\aaa).exists());System.out.println(d:/WeGame 是否是目录: file1.isDirectory());System.out.println(d:/WeGame 是否是文件: file1.isFile());System.out.println(file1 是否可读: file1.canRead());System.out.println(file1 是否可写: file1.canWrite());System.out.println(file1 是否处于隐藏状态: file1.isHidden());}
}5、创建、删除功能
public boolean createNewFile(): 创建文件文件已经存在则返回false创建失败不会覆盖文件public boolean mkdir(): 创建目录文件目录存在不创建或指定的文件目录上层目录不存在那么也不创建public boolean mkdirs(): 创建目录上层目录不存在则一并创建 【可以理解为直接创建多级目录】public boolean delete(): 删除文件或文件夹 通过Java代码删除文件不会暂时保留到回收站中直接从硬盘删除如果删除的是文件目录目录内不能包含子文件或子目录 代码演示 package com.zwh.shangguigu.fileandio_;import java.io.File;
import java.io.IOException;/** author Bonbons* version 1.0/
public class FileCreateDelete{public static void main(String[] args) throws IOException {//创建一个本来不存在的文件File f new File(d:/test/aaa.txt);System.out.println(f 是否存在: f.exists());System.out.println(创建文件是否成功: f.createNewFile());System.out.println(f 是否存在: f.exists());//创建一个本来不存在的目录上一级目录存在File f2 new File(d:/test/newDir);System.out.println(newDir是否存在: f2.exists());System.out.println(newDir是否创建: f2.mkdir());System.out.println(newDir是否存在: f2.exists());//创建一个目录但是他的上一级目录不存在System.out.println(falseDir是否创建成功: new File(d:/dask/falseDir).mkdir());//直接创建多级目录File f3 new File(d:/a/b/ccc);System.out.println(f3 是否存在: f3.exists());System.out.println(f3 是否创建成功: f3.mkdirs());System.out.println(f3 是否存在: f3.exists());//删除创建的文件System.out.println(删除d:/test/aaa.txt是否成功: f.delete());//删除目录删除d:/a/b/ccc它是一个空目录System.out.println(删除d:/a/b/ccc的ccc目录是否成功: f3.delete());//试图直接删除d:/a,删除失败因为它有一个子目录bSystem.out.println(删除d:/a是否成功: new File(d:/a).delete());}
}6、综合练习
1判断指定目录下是否有后缀名为 .jpg的文件。如果有就输出该文件名称
endWith 可以判断字符串是否以指定的片段结尾 一种通过 list() 方法获取所有子文件及子目录的String数组另一种通过 listFiles() 方法获取所有子文件及子目录的File数组调用File提供的getName()方法获取文件名 通过重写listFiles()方法的过滤器规则也就是accept方法 返回的File数组都是满足要求的数组
public class FindJPGFileTest {//方法1Testpublic void test1(){File srcFile new File(d:\code);String[] fileNames srcFile.list();for(String fileName : fileNames){if(fileName.endsWith(.jpg)){System.out.println(fileName);}}}//方法2Testpublic void test2(){File srcFile new File(d:\code);File[] listFiles srcFile.listFiles();for(File file : listFiles){if(file.getName().endsWith(.jpg)){System.out.println(file.getAbsolutePath());}}}//方法3/** File类提供了两个文件过滤器方法 public String[] list(FilenameFilter filter)* public File[] listFiles(FileFilter filter)/Testpublic void test3(){File srcFile new File(d:\code);File[] subFiles srcFile.listFiles(new FilenameFilter() {Overridepublic boolean accept(File dir, String name) {return name.endsWith(.jpg);}});for(File file : subFiles){System.out.println(file.getAbsolutePath());}}
}2遍历指定目录所有文件名称包括子文件目录中的文件
遇到目录就递归处理否则就打印文件地址【参考下面两个方案】
public static void printSubFile(File dir) {// 打印目录的子文件File[] subfiles dir.listFiles();for (File f : subfiles) {if (f.isDirectory()) {// 文件目录printSubFile(f);} else {// 文件System.out.println(f.getAbsolutePath());}}
}public void listAllSubFiles(File file) {if (file.isFile()) {System.out.println(file);} else {File[] all file.listFiles();// 如果all[i]是文件直接打印// 如果all[i]是目录接着再获取它的下一级for (File f : all) {listAllSubFiles(f);// 递归调用自己调用自己就叫递归}}
}3计算指定目录占用空间大小
public long getDirectorySize(File file) {// file是文件那么直接返回file.length()// file是目录把它的下一级的所有file大小加起来就是它的总大小long size 0;if (file.isFile()) {size file.length();} else {File[] all file.listFiles();// 获取file的下一级// 累加all[i]的大小for (File f : all) {size getDirectorySize(f);// f的大小;}}return size;
}4删除指定文件目录及其下的所有文件
public void deleteDirectory(File file) {// 如果file是文件直接delete// 如果file是目录先把它的下一级干掉然后删除自己if (file.isDirectory()) {File[] all file.listFiles();// 循环删除的是file的下一级for (File f : all) {// f代表file的每一个下级deleteDirectory(f);}}// 删除自己file.delete();
}二、IO流的原理及流的分类
2.1 Java IO原理
Java程序中对于数据的输入/输出操作以流(stream)的方式进行可以看做是一种数据的流动 I/O流代表 Input/Output 的缩写用于处理设备之间的数据传输【如读写文件、网络通讯】 输入input: 读取外部数据磁盘、光盘等存储设备的数据到程序内存中输出 output将程序内存数据输出到磁盘、光盘等存储设备中 2.2 流的分类 java.io 包下提供了各种流类和接口用以获取不同种类的数据并通过标准的方法输入或输出数据 按数据的流向不同分为输入流和输出流 输入流把数据从 其他设备 读取到 内存 中的流 以 InputStream、Reader 结尾 输出流把数据从 内存 中写出到 其他设备上的流 以 OutputStream、Writer 结尾 按操作数据单位的不同分为字节流(8bit) 和 字符流(16bit) 字节流以字节为单位读写数据的流 【InputStream、OutputStream结尾】字符流以字符为单位读写数据的流 【Reader、Writer结尾】 根据 IO 角色不同分为节点流 和 处理流 节点流直接从数据源或目的地读写数据 处理流不直接连接到数据源或目的地而是连接在已存在的流节点流或处理流之上通过对数据的处理为程序提供更为强大的读写功能 一图总结 2.3 流的API
Java 由四个抽象基类派生出40多个IO流 派生出来的子类都以其父类名作为后缀 常见的字节流 文件流 FileInputStream、FileOutputStream、FileReader、FileWriter字节/字符数组流ByteArrayInputStream、ByteArrayOutputStream、CharArrayReader、CharArrayWriter 对数组进行处理的节点流对应的不再是文件而是内存中的一个数组 常用处理流 缓冲流BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter 作用增加缓冲功能避免频繁读写硬盘进而提升读写效率 转换流InputStreamReader、OutputStreamReader 作用实现字节流和字符流的转换 对象流ObjectInputStream、ObjectOutputStream 作用提供直接读写Java对象功能
三、 FileReader 和 FileWriter
3.1 Reader 与 Writer
Java提供一些字符流类以字符为单位读写数据专门用于处理文本文件。 .txt、.java、.c、.cpp、.py等都是文本文件图片、视频、.doc、.xls、.ppt都不是文本文件 1、字符输入流Reader
java.io.Reader 抽象类是所有用于读取字符流的所有类的父类可以读取字符信息到内存中它定义了字符输入流的基本共性功能方法 public int read(): 从输入流读取一个字符 自动提升为 int返回该字符的Unicode编码值如果已经达到流末尾则返回 -1public int read(char [] cbuf):从输入流读取一些字符并将他们存储到字符数组 cbuf中每次最多读取 cbuf.length个字符。返回实际读取的字符个数。如果已经到流末尾没有数据可读则返回 -1public int read(char [] cbuf, int off, int len): 从输入流中读取一些字符并将它们存储到字符数组 cbuf中从cbuf[off]开始的位置存储。每次最多读取len个字符。返回实际读取的字符个数。如果已经到达流末尾没有数据可读则返回-1public void close(): 关闭此流并释放与此流相关联的任何系统资源 It’s importent: 当完成流的操作时必须调用close()方法释放系统资源否则会造成内存泄漏 2、字符输出流Writer
java.io.Writer 抽象类是表示用于写出字符流的所有类的超类将指定的字符信息写到目的地。它定义了字节输出流的基本共性功能方法 public void write(int c): 写出单个字符 public void write(char [] cbuf): 写出字符数组 public void write(char [] cbuf, int off, int len): 写出字符数组的一部分 off 是数组的开始索引len 是写出的字符个数 public void write(String str): 写出字符串 public void write(String str, int off, int len):写出字符串的某一部分 off 是字符串的开始索引len 是写出的字符个数 public void flush(): 刷新该流的缓冲 public void close(): 关闭此流 和字符输入流一样在完成流操作之后要调用 close 方法释放资源否则可能会导致内存泄漏的问题 3.2 FileReader 与 FileWriter 1、FileReader
java.io.FileReader 类用于读取字符文件构造时使用系统默认的字符编码和默认字节缓冲区 FileReader(File file): 创建一个新的FileReader给定要读取的File对象FileReader(String fileName):创建一个新的FileReader给定要读取的文件的名称 通过代码演示——如何从一个具体的文件中读取数据 package com.zwh.shangguigu.fileandio_;import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;/** author Bonbons* version 1.0/
public class FileReaderWriterTest {public static void main(String[] args) {//创建文件类读取的对象FileReader fr null;//捕获一下可能存在的IOExceptiontry{//创建File类的对象对应着物理磁盘上的某个文件File file new File(d:/test/zbc.txt);//创建FileReader流对象将File类的对象作为参数传递到FileReader的构造器中try{fr new FileReader(file);}catch (FileNotFoundException e){e.printStackTrace();}int data 0;//这里如果不将读取的字符赋值给data就会出现乱码我还不知道为啥while((data fr.read()) ! -1){System.out.print((char)data);}}catch (IOException e){e.printStackTrace();}finally {//4、关闭相关的流资源避免出现内存泄漏try{if(fr ! null){fr.close();}}catch (IOException e){e.printStackTrace();}}}
}如果向一次读多个字符那么就设置一个字符数组作为参数传递到 read()方法中 输出的时候用这个字符数组构造成字符串然后再打印输出 2、FileWriter
java.io.FileWriter 类用于写出字符到文件构造时使用系统默认的字符编码和默认字符缓冲区 FileWriter(File file): 创建一个新的FileWriter给定要读取的 File 对象FileWriter(String fileName): 创建一个新的FileWriter给定要读取的文件名称FileWriter(File file, boolean append): 创建一个新的 FileWriter指明是否在现有文件末尾追加内容 代码演示 package com.zwh.shangguigu.fileandio_;import java.io.File;
import java.io.FileWriter;
import java.io.IOException;/** author Bonbons* version 1.0/
public class FWWrite {public static void main(String[] args) {try{FileWriter fw new FileWriter(new File(d:/test/zbc));char [] ch {a, b, c};String s zhenbucuo;try{fw.write(z);fw.write(ch);fw.write(ch, 1, 2);fw.write(s);fw.write(s, 2, 3);//关闭资源fw.close();}catch (IOException e){e.printStackTrace();}}catch (IOException e){e.printStackTrace();}}
}总结 因为出现流资源的调用为了避免内存泄漏需要使用try-catch-finally处理异常 对于输入流来说File类的对象必须在物理磁盘上存在否则执行就会报FileNotFoundException。如果传入的是一个目录则会报IOException异常。 对于输出流来说File类的对象是可以不存在的。 如果File类的对象不存在则可以在输出的过程中自动创建File类的对象如果File类的对象存在如果调用FileWriter(File file)或FileWriter(File file,false)输出时会新建File文件覆盖已有的文件如果调用FileWriter(File file,true)构造器则在现有的文件末尾追加写出内容。 四、FileInputStream 和 FileOutputStream
对于Reader、Writer是对字符流进行操作的也就是说不能处理非文本文件那么我们如何使用字节流来读取、写入数据呢
4.1 InputStream 与 OutputStream 1、字节输入流InputStream
java.io.InputStream 抽象类表示字节输入流的所有类的超类可以读取字节信息到内存中它定义了字节输入流的基本共性功能方法 public int read(): 从输入流读取一个字节。返回读取的字节值。虽然读取了一个字节但是会自动提升为int类型。如果已经到达流末尾没有数据可读则返回-1public int read(byte [] b): 从输入流中读取一些字节数并将它们存储到字节数组 b中 。每次最多读取b.length个字节。返回实际读取的字节个数。如果已经到达流末尾没有数据可读则返回-1public int read(byte [] b, int off, int len): 从输入流中读取一些字节数并将它们存储到字节数组 b中从b[off]开始存储每次最多读取len个字节 。返回实际读取的字节个数。如果已经到达流末尾没有数据可读则返回-1public void close(): 关闭次输入流并释放与此流相关的任何系统资源 【完成流操作后必须调用此方法】 2、字节输出流OutputStream
java.io.OutputStream 抽象类是表示字节输出流的所有类的超类将指定的字节信息写出到目的地它定义了字节输出流的基本共性功能方法 public void write(int b): 将指定的字节输出流写出。虽然参数为int类型四个字节但是只会保留一个字节的信息写出public void write(byte [] b): 将 b.length字节从指定的字节数组写入此输出流public void write(byte [] b, int off, int len): 从指定的字节数组写入 len字节从偏移量 off开始输出到此输出流public void flush(): 刷新此输出流并强制任何缓冲的输出字节被写出public void close(): 关闭此输出流并释放与此流相关联的任何系统资源 【完成流操作就调用】
4.2 FileInputStream 与 FileOutputStream 1、FileInputStreamStream
java.io.FileInputStream 类是文件输入流从文件中读取字节 FileInputStream(File file): 通过打开与实际文件的连接来创建一个 FileInputStream该文件由文件系统中File对象file命名FileInputStream(String name): 通过打开域实际文件的连接来创建一个FileInputStream该文件由系统中的路径名 name 命名 通过代码演示字节流文件的读取操作 package com.zwh.shangguigu.fileandio_;import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InvalidObjectException;/** author Bonbons* version 1.0/
public class FISRead {public static void main(String[] args) throws IOException {//先准备一个文件File f new File(d:/test/abc.txt);
// f.createNewFile();//为了省事我直接抛出了//演示几种以字节流的方式读取文件的操作FileInputStream fis new FileInputStream(f);FileInputStream fis2 new FileInputStream(f);FileInputStream fis3 new FileInputStream(f);FileInputStream fis4 new FileInputStream(f);//需要用read存一下read()方法返回的是一个字节int read fis.read();System.out.println((char)read);fis.close();System.out.println(********************);while((read fis2.read()) ! -1){System.out.println((char)read);}fis2.close();System.out.println(******************);//准备一个字节数组byte [] b new byte[2];int len 0;while((len fis3.read(b)) ! -1){System.out.println(new String(b));}fis3.close();System.out.println(***************);while((len fis4.read(b)) ! -1){System.out.println(new String(b, 0, len));}fis4.close();}
}2、FileOutputStream
java.io.FileOutputStream 类是文件输出流用于将数据写出到文件 public FileOutpurStream(File file): 创建文件输出流写出由指定的File对象表示的文件public FileOutputStream(String name): 创建文件输出流指定的名称为写出文件public FIleOutputStream(File file, boolean append): 创建文件输出流指明是否在现有文件末尾追加内容 通过代码来演示具体的用法 package com.zwh.shangguigu.fileandio_;import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;/ author Bonbons* version 1.0/
public class FOSWrite {public static void main(String[] args) throws IOException {//使用File对象创建流对象FileOutputStream fos new FileOutputStream(new File(d:/test/abc.txt));//写入一个字节fos.write(97);//写入一个字节数组byte [] b abcd.getBytes();fos.write(b);//写入字节数组的一部分fos.write(b, 1, 2); //bc//使用FileInputStream读取一下文件FileInputStream fis new FileInputStream(d:/test/abc.txt);int data 0;while((data fis.read()) ! -1){System.out.println((char)data);}fis.close();fos.close();//写入结果aabcdbc覆盖了原来的内容}
}3、通过几个案例来练习一下
1实现文件的copy功能就是将一个文件的读取结果写入到另一个文件中
我们以 d:/test/a.txt 和 d:/test/b.txt为例a.txt 中的内容为 I love China.
package com.zwh.shangguigu.fileandio_;import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;/** author Bonbons* version 1.0/
public class FIOSCopyTest {public static void main(String[] args) {FileInputStream fis null;FileOutputStream fos null;try{fis new FileInputStream(new File(d:/test/a.txt));fos new FileOutputStream(d:/test/b.txt);//因为InputStream、OutputStream操作的是字节流byte [] buffer new byte[1024];int len 0;while((len fis.read(buffer)) ! -1){fos.write(buffer, 0, len);}System.out.println(内容复制成功!);}catch (IOException e){e.printStackTrace();throw new RuntimeException(e);}finally {//最后我们要释放资源try{if(fis ! null){fis.close();}}catch (IOException e){e.printStackTrace();throw new RuntimeException(e);}try{if(fos ! null){fos.close();}}catch (IOException e){e.printStackTrace();throw new RuntimeException(e);}}//最后我们再检查一下是否写入成功try{FileInputStream fis2 new FileInputStream(d:/test/b.txt);int data 0;while((data fis2.read()) ! -1){System.out.print((char)data);}}catch (IOException e){e.printStackTrace();}}
}2实现图片的加密和解密操作 加密提示在Java中 ^ 代表异或操作采用异或一个特定值加密那么解密再次异或这个特定值就可以 package com.zwh.shangguigu.fileandio_;import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;/** author Bonbons* version 1.0* 图片的加密与解密/
public class FileSecretTest {public static void main(String[] args) {encryption();decryption();}//加密 [实际应该把加密的功能抽出来但是我为了在一个类中实现// 加密和解密就把完整操作放在一个静态方法中了通过主方法// 调用来完成测试]public static void encryption(){FileInputStream fis null;FileOutputStream fos null;try{fis new FileInputStream(new File(d:/test/kun.jpg));fos new FileOutputStream(d:/test/kun_secret.jpg);//每次读取一个字节效率很低所以采用1024字节数组读取byte [] buffer new byte[1024];int len 0;while((len fis.read(buffer)) ! -1){//对每一个字节都进行加密for(int i 0; i len; i){//需要强转因为与5异或会自动将精度提升为intbufferi(buffer[i] ^ 5);}//写到字节输出流中fos.write(buffer, 0, len);}System.out.println(图片加密成功!);}catch (IOException e){//在实际开发中打印异常信息到控制台很少大多采用抛出异常来提醒出问题了e.printStackTrace();throw new RuntimeException(e);}finally{//资源释放try{if(fis ! null){fis.close();}}catch (IOException e){throw new RuntimeException(e);}try{if(fos ! null){fos.close();}}catch (IOException e){throw new RuntimeException(e);}}}//图片的解密public static void decryption(){FileInputStream fis null;FileOutputStream fos null;try{fis new FileInputStream(new File(d:/test/kun_secret.jpg));fos new FileOutputStream(d:/test/kun_unsecret.jpg);int len 0;byte [] buffer new byte[1024];while((len fis.read(buffer)) ! -1){//解密for(int i 0; i len; i){bufferi (buffer[i] ^ 5);}//将解密后的字节数组写入到目标数据流中fos.write(buffer, 0, len);}System.out.println(图片解密成功!);}catch (IOException e){throw new RuntimeException(e);}finally {try{if (fos ! null) {fos.close();}}catch (IOException e){throw new RuntimeException(e);}try{if (fis ! null) {fis.close();}}catch (IOException e){throw new RuntimeException(e);}}}
}五、缓冲流
为了提供数据读写速度Java API 提供了带缓冲功能的流类缓冲流缓冲流要 “套接” 在相应的节点流之上根据数据操作单位可以把缓冲流分为 字节缓冲流 BufferedInputStream、BufferedOutputStream字符缓冲流BufferedReader、BufferedWriter 缓冲流的基本原理在创建流对象时内部会创建一个缓冲区数组缺省使用8192个字节(8Kb的缓冲区通过缓冲区读写减少系统IO次数从而提高读写的效率 5.1 构造器
字节缓冲流构造器 public BufferedInputStream(InputStream in): 创建一个新的字节型的缓冲输入流public BufferedOutputStream(OutputStream out ):创建一个新的字节型的缓冲输出流 代码演示: BufferedInputStream bis new BufferedInputStream(new FileInputStream(abc.jpg));
BufferedOutputStream bos new BufferedOutputStream(new FileOutputStream(abccopy.jpg));字符缓冲流构造器 public BufferedReader(Reader in):创建一个新的字符型的缓冲输入流public BufferedWriter(Writer out): 创建一个新的字符型的缓冲输出流 代码演示 BufferedReader br new BufferedReader(new FileReader(br.txt));
BufferedWriter bw new BufferedWriter(new FileWriter(bw.txt));5.2 效率测试 查询API缓冲流读写方法与基本的流是一致的我们通过复制大文件测试他们的读写效率 package com.zwh.shangguigu.fileandio;import java.io.;/*** author Bonbons* version 1.0* 比较普通流和缓冲流的复制文件速度/
public class CopyFileWithFileStream {public static void main(String[] args) {String srcPath d:/test/Flutter.rar;String destPath d:/test/copy_Flutter.rar;long start System.currentTimeMillis();ordinaryStream(srcPath, destPath);long end System.currentTimeMillis();System.out.println(ordinary流完成复制花费的时间为: (end - start));start System.currentTimeMillis();bufferedStream(srcPath, d:/test/copy2Flutter.rar);end System.currentTimeMillis();System.out.println(bufferedStream流完成复制花费的时间为: (end - start));}//普通流完成文件copypublic static void ordinaryStream(String srcPath, String destPath){//创建字节流文件读取的对象FileInputStream fis null;FileOutputStream fos null;try{fis new FileInputStream(new File(srcPath));fos new FileOutputStream(new File(destPath));//复制操作byte [] buffer new byte[100];int len 0;while((len fis.read(buffer)) ! -1){fos.write(buffer, 0, len);}System.out.println(复制成功!);}catch (IOException e){throw new RuntimeException(e);}finally{try{if (fis ! null) {fis.close();}}catch (IOException e){throw new RuntimeException(e);}try{if (fos ! null) {fos.close();}}catch (IOException e){throw new RuntimeException(e);}}}public static void bufferedStream(String srcPath, String destPath){//字节输入输出流对象以及字节缓冲输入输出流对象FileInputStream fis null;FileOutputStream fos null;BufferedInputStream bis null;BufferedOutputStream bos null;try{fis new FileInputStream(new File(srcPath));fos new FileOutputStream(new File(destPath));bis new BufferedInputStream(fis);bos new BufferedOutputStream(fos);//copyint len 0;byte [] buffer new byte[100];while((len bis.read(buffer)) ! -1){bos.write(buffer, 0, len);}System.out.println(复制成功!);}catch (IOException e){throw new RuntimeException(e);}finally{try{if (bos ! null) {bos.close();}}catch (IOException e){throw new RuntimeException(e);}try{if(bis ! null){bis.close();}}catch (IOException e){throw new RuntimeException(e);}}}
}5.3 字符缓冲流特有方法
字符缓冲流的基本方法与普通字符流调用方法一致以下为特有方法 BufferedReader: public String readLine(): 读一行文字BufferedWriter: public void newLine(): 写一行行分隔符由系统属性定义符号 通过代码演示一下具体的用法: package com.zwh.shangguigu.fileandio;import java.io.;/*** author Bonbons* version 1.0*/
public class BufferedIOLine {public static void main(String[] args) {//演示readLinetry{BufferedReader br new BufferedReader(new FileReader(new File(d:/test/cc.txt)));//定义一个字符串保存读取的一行文字String line ;while((line br.readLine()) ! null){System.out.println(line);}br.close();}catch (IOException e){e.printStackTrace();}//演示写入换行try{BufferedWriter bw new BufferedWriter(new FileWriter(new File(d:/test/cc.txt)));bw.write(奇衡三);bw.newLine();bw.write(可以);bw.write(召唤);bw.newLine();bw.write(魁拔的脉兽);bw.flush();bw.close();}catch (IOException e){e.printStackTrace();}}
}我们可以发现中华文化博大精深没有了因为被新写入的文件覆盖掉了还有一个重点内容我们需要知道 涉及到嵌套的多个流时如果都显式关闭的话需要先关闭外层的流再关闭内层的流其实在开发中只需要关闭最外层的流即可因为在关闭外层流时内层的流也会被关闭 我们通过一个练习来进一步数据缓冲流 public static void main(String[] args) {//key对应姓value为出现次数HashMapString, Integer map new HashMap();//之所以要选取字符缓冲流是因为要用它特有的readLine()读取一行数据BufferedReader br null;try {br new BufferedReader(new FileReader(new File(e:/name.txt)));String value null; // 临时接收文件中的字符串变量StringBuffer buffer new StringBuffer();flag:while ((value br.readLine()) ! null) { // 开始读取文件中的字符char[] c value.toCharArray();for (int i 0; i c.length; i) {//拼接姓到buffer里注意姓可能不是一个字if (c[i] ! ) {buffer.append(String.valueOf(c[i]));} else {//我用了HashMap的getOrDefault优化了一下if(map ! null){map.put(buffer.toString(), map.getOrDefault(buffer.toString(), 0) 1);}else{map.put(buffer.toString(), 1)/if (map.containsKey(buffer.toString())) {int count map.get(buffer.toString());map.put(buffer.toString(), count 1);} else {map.put(buffer.toString(), 1);}///目的是将buffer重置为空串buffer.delete(0, buffer.length());continue flag;}}}} catch (Exception e) {e.printStackTrace();} finally {if (br ! null) {try {br.close();} catch (IOException e) {e.printStackTrace();}}}//排序SetMap.EntryString, Integer set map.entrySet();IteratorMap.EntryString, Integer it set.iterator();while (it.hasNext()) {Map.EntryString, Integer end (Map.EntryString, Integer) it.next();System.out.println(end);}}六、转换流
针对文本文件现在使用一个字节流进行数据的读入希望将数据显示在控制台上对于其中的中文数据可能会出现乱码使用FileReader读取项目中的文本文件由于IDEA设置中针对项目设置了UTF-8编码当读取Windows系统中创建的文本文件时如果Windows系统默认的是GBK编码则读入内存会出现乱码那么有没有什么办法可以解决以上的问题呢 转换流是字节与字符之间的桥梁 6.1 InputStreamReader 与 OutputStreamReader 1、InputStreamReader
转换流 java.io.InputStreamReader,是Reader的子类是从字节流到字符流的桥梁。 它读取字节并使用指定的字符集将其解码为字符。它的字符集可以由名称指定也可以接受平台的默认字符集构造器 InputStreamReader(InputStream int): 创建一个使用默认字符集的字符流InputStreamReader(InputStream in, String charsetName):创建一个指定字符集的字符流
//两种构造方法演示
InputStreamReader isr new InputStreamReader(new FileInputStream(in.txt));
OutputStreamReader osr new OutputStreamReader(new FileOutputStream(out.txt));通过代码演示具体的用法 package com.zwh.shangguigu.fileandio;import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;/*** author Bonbons* version 1.0*/
public class InputStreamReaderDemo {public static void main(String[] args) throws IOException {//创建转换流的对象指定编码字符集InputStreamReader isr new InputStreamReader(new FileInputStream(new File(d:/test/a.txt)), GBK);int data 0;while((data isr.read()) ! -1){System.out.print((char)data);}System.out.println();if (isr ! null) {isr.close();}//创建字节流到字符流的转换流对象不设置编码InputStreamReader isr2 new InputStreamReader(new FileInputStream(d:/test/a.txt));int charData 0;while((charData isr2.read()) ! -1){System.out.print((char)charData);}if (isr2 ! null) {isr2.close();}}
}因为我的这个文件时UTF-8编码的为了演示出乱码的效果我就将转换流的编码设置成GBK 2、OutputStreamWriter
转换流 java.io.OutputStreamWriter,是Writer的子类从字符流到字节流的桥梁使用指定的字符集将字符编码为字节。它的字符集可以由名称指定也可以接受平台的默认字符集构造器 OutputStreamWriter(OutputStream in): 创建一个使用默认字符集的字符流OutputStreamWriter(OutputStream out, String charserName):创建一个指定字符集的字符流
OutputStreamWriter isr new OutputStreamWriter(new FileOutputStream(out.txt));
OutputStreamWriter isr2 new OutputStreamWriter(new FileOutputStream(out.txt), GBK);通过代码演示具体的使用方法 package com.zwh.shangguigu.fileandio;import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.OutputStreamWriter;/*** author Bonbons* version 1.0* 从字符流到字节流转换的桥梁/
public class OutputStreamWriterDemo {public static void main(String[] args) throws IOException {String FileName d:/test/a.txt;OutputStreamWriter osw new OutputStreamWriter(new FileOutputStream(FileName));osw.write(你好);//一个汉字在UTF-8里占3个字节osw.close();OutputStreamWriter osw2 new OutputStreamWriter(new FileOutputStream(d:/test/aaa.txt), GBK);osw2.write(你好);//一个汉字在GBK里占两个字节osw2.close();}
}6.2 字符编码和字符集 1、编码和解码的概念 计算机中存储的信息都是用二进制数表示的 按照某种规则将字符存储到计算机中称之为编码将存储在计算机中的二进制数按照某种规则解析显示出来称之为解码 字符编码Character Encoding就是一套自然语言的字符与二进制数之间的对应规则 编码表生活中文字和计算机中二进制的对应规则 什么情况下会出现乱码的现象呢 用不同的规则进行存储和解析 2、各种字符集的介绍 字符集Charset也叫编码表。是一个系统支持的所有字符的集合包括各国家文字、标点符号、图形符号、数字等。 计算机要准确的存储和识别各种字符集符号需要进行字符编码一套字符集必然至少有一套字符编码。常见字符集有ASCII字符集、GBK字符集、Unicode字符集等 可见当指定了编码它所对应的字符集自然就指定了所以编码才是我们最终要关心的
1ASCII字符集
ASCII码American Standard Code for Information Interchange美国信息交换标准代码上个世纪60年代美国制定了一套字符编码对英语字符与二进制位之间的关系做了统一规定。这被称为ASCII码。ASCII码用于显示现代英语主要包括控制字符回车键、退格、换行键等和可显示字符英文大小写字符、阿拉伯数字和西文符号。基本的ASCII字符集使用7位bits表示一个字符最前面的1位统一规定为0共128个字符。比如空格“SPACE”是32二进制00100000大写的字母A是65二进制01000001。缺点不能表示所有字符。
2ISO-8859-1字符集
拉丁码表别名Latin-1用于显示欧洲使用的语言包括荷兰语、德语、意大利语、葡萄牙语等ISO-8859-1使用单字节编码兼容ASCII编码。
3GBxxx字符集
GB就是国标的意思是为了显示中文而设计的一套字符集。GB2312简体中文码表。一个小于127的字符的意义与原来相同即向下兼容ASCII码。但两个大于127的字符连在一起时就表示一个汉字这样大约可以组合了包含7000多个简体汉字此外数学符号、罗马希腊的字母、日文的假名们都编进去了这就是常说的全角字符而原来在127号以下的那些符号就叫半角字符了。GBK最常用的中文码表。是在GB2312标准基础上的扩展规范使用了双字节编码方案共收录了21003个汉字完全兼容GB2312标准同时支持繁体汉字以及日韩汉字等。GB18030最新的中文码表。收录汉字70244个采用多字节编码每个字可以由1个、2个或4个字节组成。支持中国国内少数民族的文字同时支持繁体汉字以及日韩汉字等。
4Unicode字符集
Unicode编码为表达任意语言的任意字符而设计也称为统一码、标准万国码Unicode 将世界上所有的文字用2个字节统一进行编码为每个字符设定唯一的二进制编码以满足跨语言、跨平台进行文本处理的要求。Unicode 的缺点这里有三个问题 第一英文字母只用一个字节表示就够了如果用更多的字节存储是极大的浪费第二如何才能区别Unicode和ASCII计算机怎么知道两个字节表示一个符号而不是分别表示两个符号呢第三如果和GBK等双字节编码方式一样用最高位是1或0表示两个字节和一个字节就少了很多值无法用于表示字符不够表示所有字符。 Unicode在很长一段时间内无法推广直到互联网的出现为解决Unicode如何在网络上传输的问题于是面向传输的众多 UTFUCS Transfer Format标准出现。具体来说有三种编码方案UTF-8、UTF-16和UTF-32。
5UTF-8字符集
Unicode是字符集UTF-8、UTF-16、UTF-32是三种将数字转换到程序数据的编码方案。顾名思义UTF-8就是每次8个位传输数据而UTF-16就是每次16个位。其中UTF-8 是在互联网上使用最广的一种 Unicode 的实现方式。互联网工程工作小组IETF要求所有互联网协议都必须支持UTF-8编码。所以我们开发Web应用也要使用UTF-8编码。UTF-8 是一种变长的编码方式。它使用1-4个字节为每个字符编码编码规则 128个US-ASCII字符只需一个字节编码。拉丁文等字符需要二个字节编码。大部分常用字含中文使用三个字节编码。其他极少使用的Unicode辅助字符使用四字节编码。 在中文操作系统上ANSI美国国家标准学会、AMERICAN NATIONAL STANDARDS INSTITUTE: ANSI编码即为GBK在英文操作系统上ANSI编码即为ISO-8859-1 七、数据流、对象流
7.1 数据流与对象流的说明 如果需要将内存中定义的变量包括基本数据类型或引用数据类型保存在文件中那怎么办呢 Java提供了数据流和对象流来处理这些类型的数据 数据流: DataOutputStream、DataInputStream DataOutputStream: 允许应用程序将基本数据类型、String类型的变量写入输出流中DataInputStream允许应用程序以与机器无关的方式从底层输入流中读取基本数据类型、String类型的变量 数据输入流和数据输出流的方法类似【read-write相互替换即可】 数据输入、输出流存在弊端就是只支持基本数据类型和String类的读写 然而对象流既支持基本数据类型的读写又支持Java对象的读写 对象流ObjectOutputStream、ObjectInputStream ObjectOutputStream: 将Java基本数据类型和对象写入字节输出流中 通过在流中使用文件可以实现Java各种基本数据类型的数据以及对象的持久化存储 ObjectInputStream: 对以前使用 ObjectOutputStream写出的基本数据类型的数据和对象进行读入操作保存在内存中 对象流最大的优势就是可以把Java对象写入到数据源中也可以把对象从数据源中还原回来 7.2 对象流API 1、ObjectOutputStream 的构造器与常用方法
ObjectOutputStream中的构造器 public ObejectOutputStream(OutputStream out): 创建一个指定的ObjectOutputStream ObjectOutputStream 中的常用方法: public void writeBoolean(boolean val)写出一个 boolean 值。public void writeByte(int val)写出一个8位字节public void writeShort(int val)写出一个16位的 short 值public void writeChar(int val)写出一个16位的 char 值public void writeInt(int val)写出一个32位的 int 值public void writeLong(long val)写出一个64位的 long 值public void writeFloat(float val)写出一个32位的 float 值。public void writeDouble(double val)写出一个64位的 double 值public void writeUTF(String str)将两个字节的长度信息写入输出流其后是字符串 s中每个字符的s 。 如果s是null 则抛出一个NullPointerException 。 字符串s中的每个字符根据字符的值s为一个两个或三个字节的组public void writeObject(Object obj)写出一个obj对象public void close() 关闭此输出流并释放与此流相关联的任何系统资源 2、ObjectInputStream 的构造器与常用方法:
ObjectInputStream中的构造器 public ObjectInputStream(InputStream in): 创建一个指定的ObjectInputStream ObjectInputStream 中的常用方法: public boolean readBoolean()读取一个 boolean 值public byte readByte()读取一个 8 位的字节public short readShort()读取一个 16 位的 short 值public char readChar()读取一个 16 位的 char 值public int readInt()读取一个 32 位的 int 值public long readLong()读取一个 64 位的 long 值public float readFloat()读取一个 32 位的 float 值public double readDouble()读取一个 64 位的 double 值public String readUTF()读取 UTF-8 修改版格式的 Stringpublic void readObject(Object obj)读入一个obj对象public void close() 关闭此输入流并释放与此流相关联的任何系统资源
7.3 认识对象序列化机制 1、什么是对象序列化机制 对象序列化机制允许把内存中的Java对象转化成与平台无关的二进制流。从而把这种二进制流持久地保存在磁盘上或通过网络将这种二进制流传输到另一个网络节点。 序列化机制包括两个过程 序列化过程用一个字节序列可以表示一个对象该字节序列包括该 对象的类型 和 对象中存储的属性 等信息。字节序列写出到文件之后相当于文件中 持久保存 了一个对象的信息反序列化过程该字节序列还可以从文件中读取回来重构对象对它进行反序列化。其中对象的数据、对象的类型和对象中存储的数据信息都可以用来在内存中创建对象 2、序列化机制有什么意义 序列化是 RMIRemote Method Invoke、远程方法调用过程的参数和返回值都必须实现的机制而 RMI 是 JavaEE 的基础。因此序列化机制是 JavaEE 平台的基础。 序列化的好处在于可将任何实现了Serializable接口的对象转化为字节数据使其在保存和传输时可被还原 3、序列化机制的实现原理是什么
序列化用ObjectOutputStream类保存基本类型数据或对象的机制。方法为 public final void writeObject (Object obj) : 将指定的对象写出。 反序列化用ObjectInputStream类读取基本类型数据或对象的机制。方法为 public final Object readObject () : 读取一个对象。 4、如何实现序列化机制 如果我们想让某个对象支持序列化机制就必须让其所属类实现 java.io.Serializable 接口 通过代码来演示如何完成序列化和反序列化 如果有多个对象需要序列化可以将对象放到集合中再序列化集合对象即可
package com.zwh.shangguigu.fileandio_;import java.io.;/*** author Bonbons* version 1.0/
public class ReadWriteObject {public static void main(String[] args) {//创建学生类对象Student s new Student(042040133, JiaSiting, 21);//序列化try{//创建对象输入流将我们的Java对象写入到指定的文件中File f new File(d:/test/student.txt);ObjectOutputStream oos new ObjectOutputStream(new FileOutputStream(f));oos.writeObject(s);oos.close();System.out.println(Serialized data is saved);}catch (IOException e){e.printStackTrace();}//反序列化try{ObjectInputStream ois new ObjectInputStream(new FileInputStream(new File(d:/test/student.txt)));try{Student stu (Student) ois.readObject();ois.close();System.out.println(stu);}catch (ClassNotFoundException e){e.printStackTrace();}}catch (IOException e){e.printStackTrace();}}}//创建学生类让它实现Serializable接口使其对象支持序列化机制
class Student implements Serializable {private String sno;private String sname;private int age;public Student(String sno, String sname, int age) {this.sno sno;this.sname sname;this.age age;}public String getSno() {return sno;}public void setSno(String sno) {this.sno sno;}public String getSname() {return sname;}public void setSname(String sname) {this.sname sname;}public int getAge() {return age;}public void setAge(int age) {this.age age;}Overridepublic String toString() {return Student{ sno sno \ , sname sname \ , age age };}
}7.5 反序列化失败问题 1、反序列化失败的两种情况 对于JVM可以反序列化对象他必须是能够遭到 class 文件的类。否则会抛出 CLassNotFoundException 异常 能够找到class文件但是在序列化对象之后发生了修改那么反序列化操作也会失败会抛出 InvalidClassException 异常 有可能是该类的序列版本号与从流中读取的类描述符的版本号不匹配该类包含未知数据类型 2、那么如何解决上面的问题呢
Serializable 接口给需要序列化的类提供了一个序列化版本号serialVersionUID 凡是实现 Serializable 接口的类都应该有一个表示序列化版本标识符的静态变量
static final long serialVersionUID 234242343243L; //它的值由程序员随意指定即可。serialVersionUID用来表明类的不同版本间的兼容性。 简单来说Java 的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。 在进行反序列化时JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较如果相同就认为是一致的可以进行反序列化否则就会出现序列化版本不一致的异常(InvalidCastException)。 如果类没有显示定义这个静态常量它的值是Java运行时环境根据类的内部细节自动生成的。若类的实例变量做了修改serialVersionUID 可能发生变化。因此建议显式声明如果声明了serialVersionUID即使在序列化完成之后修改了类导致类重新编译则原来的数据也能正常反序列化只是新增的字段值是默认值而已。
package com.atguigu.object;import java.io.Serializable;public class Employee implements Serializable {private static final long serialVersionUID 1324234L; //增加serialVersionUID
}3、综合练习
1谈谈你对java.io.Serializable接口的理解我们知道它用于序列化是空方法接口还有其它认识吗 实现了Serializable接口的对象可将它们转换成一系列字节并可在以后完全恢复回原来的样子。这一过程亦可通过网络进行。这意味着序列化机制能自动补偿操作系统间的差异。换句话说可以先在Windows机器上创建一个对象对其序列化然后通过网络发给一台Unix机器然后在那里准确无误地重新“装配”。不必关心数据在不同机器上如何表示也不必关心字节的顺序或者其他任何细节。 由于大部分作为参数的类如String、Integer等都实现了java.io.Serializable的接口也可以利用多态的性质作为参数使接口更灵活。 2要求如图 package com.zwh.shangguigu.fileandio_;import com.sun.org.apache.xpath.internal.operations.Or;import java.io.;
import java.util.ArrayList;
import java.util.Scanner;/*** author Bonbons* version 1.0* 需求说明* 网上购物时某用户填写订单订单内容为产品列表保存在“save.bin”中。* 运行时如果不存在“save.bin”则进行新订单录入如果存在则显示并计算客户所需付款。* 分析* 编写Save()方法保存对象到“save.bin”* 编写Load()方法获得对象计算客户所需付款*/
public class OrderTest {public static void main(String[] args) {ArrayListOrderInformation lists new ArrayListOrderInformation();Scanner sc new Scanner(System.in);char op y;while(op y){System.out.print(请输入产品名:);String name sc.next();System.out.print(请输入单价:);Double price sc.nextDouble();System.out.print(请输入数量:);int count sc.nextInt();//创建商品订单对象OrderInformation order new OrderInformation(name, price, count);lists.add(order);//是否继续操作System.out.print(是否继续(y/n):);op sc.next().charAt(0);}System.out.println(订单已保存);//将完整订单写到目标文件中save(lists);System.out.println();System.out.println();load();}//存储订单信息public static void save(ArrayListOrderInformation o){ObjectOutputStream oos null;try{oos new ObjectOutputStream(new FileOutputStream(new File(d:/test/save.bin)));oos.writeObject(o);}catch (IOException e){e.printStackTrace();}finally {try{if (oos ! null) {oos.close();}}catch (IOException e){e.printStackTrace();}}}//加载订单信息获取总金额public static void load(){ObjectInputStream ois null;try{ois new ObjectInputStream(new FileInputStream(new File(d:/test/save.bin)));//计算客户需要支付的总金额Double countMoney 0.0;ArrayListOrderInformation lists (ArrayListOrderInformation)ois.readObject();System.out.println(产品名 \t 单价 \t\t 数量);for(OrderInformation order : lists){countMoney order.getPrice() * order.getCount();System.out.println(order.getOrderName() \t\t order.getPrice() \t\t order.getCount());}System.out.println(您需要支付的金额为: countMoney);}catch (IOException | ClassNotFoundException e){e.printStackTrace();}}
}class OrderInformation implements Serializable {//定义一个序列号private static final long serialVersionUID 123456789L;//订单属性private String orderName;private Double price;private int count;public OrderInformation(){}public OrderInformation(String orderName, double price, int count) {this.orderName orderName;this.price price;this.count count;}public String getOrderName() {return orderName;}public void setOrderName(String orderName) {this.orderName orderName;}public double getPrice() {return price;}public void setPrice(double price) {this.price price;}public int getCount() {return count;}public void setCount(int count) {this.count count;}Overridepublic String toString() {return OrderInformation{ orderName orderName \ , price price , count count };}
}八、其他流的使用
8.1 标准输入、输出流
System.in和System.out分别代表了系统标准的输入和输出设备默认输入设备是键盘输出设备是显示器System.in的类型是InputStreamSystem.out的类型是PrintStream其是OutputStream的子类FilterOutputStream 的子类重定向通过System类的setIn、setOut 方法对默认设备进行改变 public static void setIn(InputStream in)public static void setOut(PrintStream out) 1、 通过案例来分析如何使用标准输入、输出流
从键盘输入字符串要求将读取到的整行字符串转成大写输出。然后继续进行输入操作直至当输入“e”或者“exit”时退出程序
package com.zwh.shangguigu.fileandio_;import java.io.;/** author Bonbons* version 1.0* 从键盘输入字符串要求将读取到的整行字符串转成大写输出。* 然后继续进行输入操作直至当输入“e”或者“exit”时退出程序/
public class SystemTest {public static void main(String[] args) {System.out.println(请输入信息(退出输入e 或 exit):);BufferedReader br new BufferedReader(new InputStreamReader(System.in));PrintWriter pw new PrintWriter(new OutputStreamWriter(System.out));String s null;try{while((s br.readLine()) ! null){//判断输入的是否为跳出操作if(s.equalsIgnoreCase(e) || s.equalsIgnoreCase(exit)){break;}pw.println(s.toUpperCase());pw.flush();System.out.println(继续输入信息);}}catch (IOException e){e.printStackTrace();}finally {try{//释放连接if (br ! null) {br.close();}}catch (IOException e){e.printStackTrace();}}}
}2、System类中有三个常量对象System.out、System.in、System.err
public final static InputStream in null;
public final static PrintStream out null;
public final static PrintStream err null;这三个常量对象有final声明但是却初始化为null。final声明的常量一旦赋值就不能修改那么null不会空指针异常吗这三个常量对象为什么要小写final声明的常量按照命名规范不是应该大写吗这三个常量的对象有set方法final声明的常量不是不能修改值吗set方法是如何修改它们的值的 final声明的常量表示在Java的语法体系中它们的值是不能修改的而这三个常量对象的值是由C/C等系统函数进行初始化和修改值的所以它们故意没有用大写也有set方法。 public static void setOut(PrintStream out) {checkIO();setOut0(out);
}
public static void setErr(PrintStream err) {checkIO();setErr0(err);
}
public static void setIn(InputStream in) {checkIO();setIn0(in);
}
private static void checkIO() {SecurityManager sm getSecurityManager();if (sm ! null) {sm.checkPermission(new RuntimePermission(setIO));}
}
private static native void setIn0(InputStream in);
private static native void setOut0(PrintStream out);
private static native void setErr0(PrintStream err);3、练习 Create a program named MyInput.java: Contain the methods for reading int, double, float, boolean, short, byte and String values from the keyboard. package com.atguigu.java;
// MyInput.java: Contain the methods for reading int, double, float, boolean, short, byte and
// string values from the keyboardimport java.io.;public class MyInput {// Read a string from the keyboardpublic static String readString() {BufferedReader br new BufferedReader(new InputStreamReader(System.in));// Declare and initialize the stringString string ;// Get the string from the keyboardtry {string br.readLine();} catch (IOException ex) {System.out.println(ex);}// Return the string obtained from the keyboardreturn string;}// Read an int value from the keyboardpublic static int readInt() {return Integer.parseInt(readString());}// Read a double value from the keyboardpublic static double readDouble() {return Double.parseDouble(readString());}// Read a byte value from the keyboardpublic static double readByte() {return Byte.parseByte(readString());}// Read a short value from the keyboardpublic static double readShort() {return Short.parseShort(readString());}// Read a long value from the keyboardpublic static double readLong() {return Long.parseLong(readString());}// Read a float value from the keyboardpublic static double readFloat() {return Float.parseFloat(readString());}
}8.2 打印流
实现将基本数据类型的数据格式转化为字符串输出打印流PrintStream、PrintStream 提供了一系列重载的print()和println()方法用于多种数据类型的输出 - PrintStream和PrintWriter的输出不会抛出IOException异常
- PrintStream和PrintWriter有自动flush功能- PrintStream 打印的所有字符都使用平台的默认字符编码转换为字节。在需要写入字符而不是写入字节的情况下应该使用 PrintWriter 类。- System.out返回的是PrintStream的实例构造器 PrintStream(File file) 创建具有指定文件且不带自动行刷新的新打印流PrintStream(File file, String csn)创建具有指定文件名称和字符集且不带自动行刷新的新打印流。PrintStream(OutputStream out) 创建新的打印流。PrintStream(OutputStream out, boolean autoFlush)创建新的打印流。 autoFlush如果为 true则每当写入 byte 数组、调用其中一个 println 方法或写入换行符或字节 (‘\n’) 时都会刷新输出缓冲区。PrintStream(OutputStream out, boolean autoFlush, String encoding) 创建新的打印流。PrintStream(String fileName)创建具有指定文件名称且不带自动行刷新的新打印流。PrintStream(String fileName, String csn) 创建具有指定文件名称和字符集且不带自动行刷新的新打印流。 通过代码演示具体用法自定义一个日志工具 package com.zwh.shangguigu.fileandio_;import java.io.; import java.text.SimpleDateFormat; import java.util.Date;/** author Bonbons* version 1.0/ public class LoggerTest {public static void main(String[] args) {Logger.log(调用了System类的gc()方法建议启动垃圾回收);Logger.log(调用了TeamView的addMember()方法);Logger.log(用户尝试进行登录验证失败);} }class Logger{public static void log(String msg){try{// 指向一个日志文件PrintStream out new PrintStream(new FileOutputStream(log.txt), true);// 改变输出方向System.setOut(out);// 日期当前时间Date nowTime new Date();SimpleDateFormat sdf new SimpleDateFormat(yyyy-MM-dd HH:mm:ss SSS);String strTime sdf.format(nowTime);System.out.println(strTime : msg);}catch (FileNotFoundException e){e.printStackTrace();}} }8.3 Scanner 类 构造方法 Scanner(File source): 构造一个新的 Scanner它生成的值是从指定文件扫描的Scanner(File source, String charsetName): 构造一个新的 Scanner它生成的值是从指定文件扫描的Scanner(InputStream source):构造一个新的 Scanner它生成的值是从指定的输入流扫描的Scanner(InputStream source, String charsetName) 构造一个新的 Scanner它生成的值是从指定的输入流扫描的 常用方法 boolean hasNextXxx(): 如果通过使用nextXxx() 方法此扫描器输入信息中的下一个标记可以解释为默认基数中的一个Xxx值则返回true hasNextXxx()是否还有下一个输入项其中Xxx可以是Int、Long等代表基本数据类型的字符串。如果需要判断是否包含下一个字符串可以省略Xxx. Xxx nextXxx(): 将输入信息的下一个标记扫描为一个Xxx nextXxx()获取下一个输入项。Xxx的含义与前一个方法中Xxx相同。 通过代码演示具体用法 package com.atguigu.systemio;import org.junit.Test;import java.io.; import java.util.Scanner;public class TestScanner {Testpublic void test01() throws IOException {Scanner input new Scanner(System.in);PrintStream ps new PrintStream(1.txt);while(true){System.out.print(请输入一个单词);String str input.nextLine();if(stop.equals(str)){break;}ps.println(str);}input.close();ps.close();}Testpublic void test2() throws IOException {Scanner input new Scanner(new FileInputStream(1.txt));while(input.hasNextLine()){String str input.nextLine();System.out.println(str);}input.close();} }九、apache-common包的使用 IO技术开发中代码量很大而且代码的重复率较高为此Apache软件基金会开发了IO技术的工具类commonsIO大大简化了IO开发【需要添加jar包】在导入commons-io-2.5.jar包之后内部的API都可以使用 IOUtils类的使用 - 静态方法IOUtils.copy(InputStream in,OutputStream out)传递字节流实现文件复制。
- 静态方法IOUtils.closeQuietly(任意流对象)悄悄的释放资源自动处理close()方法抛出的异常。public class Test01 {public static void main(String[] args)throws Exception {//- 静态方法IOUtils.copy(InputStream in,OutputStream out)传递字节流实现文件复制。IOUtils.copy(new FileInputStream(E:\Idea\io\1.jpg),new FileOutputStream(E:\Idea\io\file\柳岩.jpg));//- 静态方法IOUtils.closeQuietly(任意流对象)悄悄的释放资源自动处理close()方法抛出的异常。/* FileWriter fw null;try {fw new FileWriter(day21\io\writer.txt);fw.write(hahah);} catch (IOException e) {e.printStackTrace();}finally {IOUtils.closeQuietly(fw);}*/} }FileUtils类的使用 - 静态方法void copyDirectoryToDirectory(File src,File dest)整个目录的复制自动进行递归遍历参数:src:要复制的文件夹路径dest:要将文件夹粘贴到哪里去- 静态方法void writeStringToFile(File file,String content)将内容content写入到file中
- 静态方法String readFileToString(File file)读取文件内容并返回一个String
- 静态方法void copyFile(File srcFile,File destFile)文件复制public class Test02 {public static void main(String[] args) {try {//- 静态方法void copyDirectoryToDirectory(File src,File dest);FileUtils.copyDirectoryToDirectory(new File(E:\Idea\io\aa),new File(E:\Idea\io\file));//- 静态方法writeStringToFile(File file,String str)FileUtils.writeStringToFile(new File(day21\io\commons.txt),柳岩你好);//- 静态方法String readFileToString(File file)String s FileUtils.readFileToString(new File(day21\io\commons.txt));System.out.println(s);//- 静态方法void copyFile(File srcFile,File destFile)FileUtils.copyFile(new File(io\yangm.png),new File(io\yangm2.png));System.out.println(复制成功);} catch (IOException e) {e.printStackTrace();}} }
- 上一篇: dw免费网站模板微官网制作平台
- 下一篇: dw网站建设基本流程2014做网站
相关文章
-
dw免费网站模板微官网制作平台
dw免费网站模板微官网制作平台
- 站长
- 2026年02月16日
-
dw里响应式网站怎么做动漫制作专业零基础
dw里响应式网站怎么做动漫制作专业零基础
- 站长
- 2026年02月16日
-
DW建设网站过程中出现的问题济南网络seo公司
DW建设网站过程中出现的问题济南网络seo公司
- 站长
- 2026年02月16日
-
dw网站建设基本流程2014做网站
dw网站建设基本流程2014做网站
- 站长
- 2026年02月16日
-
dw网站建设教程视频教程seo优化技术培训中心
dw网站建设教程视频教程seo优化技术培训中心
- 站长
- 2026年02月16日
-
dw网站建设模板wordpress主题上的字怎么移动
dw网站建设模板wordpress主题上的字怎么移动
- 站长
- 2026年02月16日
