1.io流简介
不论是Reader,Writer,还是InputStream,OutputStream,在创建相应的对象是只是创建了相应的映射,相当于修了一条马路通向两个位置,但是本身并不参与数据的传输,数据的传输是通过数组完成的,这个传输的过程是单向的(nio的buffer是双向的)面向于流的传输(nio面向缓存数据块),对于读的时候不论基于单个字符还是基于数组,当没有可读的元素的时候返回值都是-1,有可读的时候返回的是有效数据的字节或字符长度,返回字符串的时候,在没有的情况下为null,对于一个输入流来说具有skip的方法,跳到我们制定的地方去开始输入,对于写我们可以设置为true在尾部添加,对于覆盖数据我们可以是用RandomAccessFile的seek设定覆盖的位置,对于我们对象流(序列化流)可以将一个文件保存在一个文件中,然后在另一个地方读取(读取的前提条件是相应的序列化类需要已经加载到JVM中),对于BufferedOutputStream等采用装饰模式,也就是在FileOutputStream外面包了一层,对于文件的乱码问题前面有一篇有介绍。
2.file
public classCreateFile {//创建文件
public static voidcreatFile(String filePath) throws Exception {
File file= newFile(filePath);if (!file.exists()) {
file.createNewFile();
}else{
System.err.println("文件夹以及存在");
}
}//创建文件夹
public static voidcreatFolder(String filePath) {
File file= newFile(filePath);if (!file.exists()) {
file.mkdirs();
}else{
System.err.println("文件夹以及存在");
}
}//在指定的文件下搜索文件(可以模糊查找)
public static ListFuzzySearch(String filePath, String regex) {
LinkedList lls = new LinkedList<>();
regex= ".*" + regex + ".*";
File file= newFile(filePath);if (!file.exists()) {
System.err.println("指定的目录不存在");return null;
}if (!file.isDirectory()) {
System.err.println("指定的不是目录");return null;
}
getErgodicFiles(regex, lls, file);if (lls.size() == 0) {
System.out.println("没有找到符合的信息");
}returnlls;
}//遍历文件
public static void getErgodicFiles(String regex, LinkedListlls, File file) {if(file.isDirectory()) {
File[] lfs=file.listFiles();for(File f : lfs) {if (!f.isDirectory()) {
String absolutePath=f.getAbsolutePath();if(absolutePath.matches(regex)) {
lls.add(absolutePath);
}
}else{
getErgodicFiles(regex, lls, f);
}
}
}
}//遍历文件
public static voidgetErgodicFiles(String fileName, File file) {if(file.isDirectory()) {
File[] lfs=file.listFiles();for(File f : lfs) {if (!f.isDirectory()) {
f.delete();
}else{
getErgodicFiles(fileName, f);
}
}
}
}public static voiddelete(String fileName) {
File file=getFile(fileName);if (file == null) {return;
}if (!file.isDirectory()) {
file.delete();return;
}
getErgodicFiles(fileName, file);
file.delete();
System.out.println("删除成功");
}//设置文件只读,但是可以另存为
public static voidsetOnlyRead(String fileName) {
File file=getFile(fileName);if (file == null) {return;
}
file.setReadable(true);
file.setWritable(false);
}private staticFile getFile(String fileName) {
File file= newFile(fileName);if (!file.exists()) {
System.err.println("指定的目录或者文件夹不存在不存在");return null;
}returnfile;
}public static voidmain(String[] args) throws Exception {//CreateFile.creatFile("F:/test/file");//CreateFile.creatFolder("F:/test/file1.txt");//List fuzzySearch = CreateFile.FuzzySearch("F:/test", "file");//System.out.println(fuzzySearch);//CreateFile.delete("F:/test/file1.txt");//CreateFile.setOnlyRead("F:/test/file1/file.txt");
}
}
3.new FileOutputStream与 new RandomAccessFile的区别
一个存在则新建,一个存在则覆盖覆盖,默认的seek是从0开始的,RandomAccessFile对同一文件可进行读写
4.更改某一个文件中的值然后保存
public static voidmain(String[] args) {try{
InputStream resourceAsStream4= PopertiesDemo1.class.getClassLoader()
.getResourceAsStream("cn/collection/demo/config.properties");
Properties properties= newProperties();
properties.load(resourceAsStream4);
System.out.println(properties.getProperty("name"));
properties.setProperty("name", "李四");
System.out.println(properties.getProperty("name"));
FileWriter fileWriter = new FileWriter("config1");//"aa" 描述信息
properties.store(fileWriter, "aa");
fileWriter.close();
}catch(Exception e) {
System.out.println("没有找到文件");
}
}
5.对象流
实现Externalizable接口,Externalizable继承了Serializable 接口,Externalizable中有两个方法需要重写writeExternal及readExternal,在writeObject和readObject时会调用相应的方法。
transient关键字表示瞬态的,在保存的是是后不会被保存进对象流,假如我么依旧添加,那么可以使用如下方法
public classPerson implements Serializable {privateString adress;//transient 关键字 表示瞬态 假如需要保存这个那么需要单独的去保存
private transient intage;private staticString name;private transient static intid;publicString getAdress() {returnadress;
}public voidsetAdress(String adress) {this.adress =adress;
}public static intgetId() {returnid;
}public void setId(intid) {this.id =id;
}publicPerson() {
super();
}public Person(int age, String adress, intid, String name) {
super();this.age =age;this.adress =adress;this.id =id;this.name =name;
}public staticString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}public intgetAge() {returnage;
}public void setAge(intage) {this.age =age;
}//一定要为私有才可以被调用
private voidwriteObject(ObjectOutputStream stream) throws IOException {//将非静态的非瞬态的保存在对象流中
stream.defaultWriteObject();
stream.writeObject(age);stream.close();
}//一定要为私有才可以被调用
private voidreadObject(ObjectInputStream stream) throws ClassNotFoundException, IOException {
stream.defaultReadObject();
age= (int) (stream.readObject());stream.close();
}
@OverridepublicString toString() {return "Person [age=" + age + ", adress=" + adress + ",name=" + name + ",id=" + id + "]";
}
}
6.分段读取文件,每次只保存一部分(网络版的在爬虫中)
public class SegmentedReadFile extends Thread {
private volatile boolean flag = false;
@Override
public void run() {
try {
Scanner scanner = new Scanner(System.in);
String nextLine = scanner.nextLine();
if (nextLine.equals("true")) {
this.flag = true;
}
} catch (Exception e) {
}
}
public boolean test(String src, String target) throws IOException {
File file = new File(src);
File file2 = new File(target);
// 这里以单个文件为例
if (file.isDirectory()) {
System.out.println("该路径是文件夹不是文件");
return false;
}
if (!file.isFile()) {
System.out.println("该文件路径不存在");
return false;
}
if (!file2.isFile()) {
try {
file2.createNewFile();
} catch (IOException e) {
return false;
}
}
FileInputStream fileInputStream=null;
BufferedInputStream bufferedInputStream=null;
FileOutputStream fileOutputStream=null;
BufferedOutputStream bufferedOutputStream=null;
if (file2.isFile()) {
long lg1 = file.length();
int segment = 24000000;
fileInputStream = new FileInputStream(file);
bufferedInputStream = new BufferedInputStream(fileInputStream);
fileOutputStream = new FileOutputStream(file2, true);
bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
byte[] bys = new byte[1024];
if (file.length() - file2.length() >= segment) {
long lg = file2.length();
bufferedInputStream.skip(lg);
for (int i = 0; i <= segment / 1024; i++) {
if (flag) {
break;
}
bufferedInputStream.read(bys);
if (i < segment / 1024 ) {
bufferedOutputStream.write(bys, 0, 1024);
} else {
bufferedOutputStream.write(bys, 0, segment%1024);
}
}
} else if(file.length() - file2.length()>0){
long lg = file2.length();
bufferedInputStream.skip(lg);
long lastSize=file.length() - file2.length();
for (int i = 0; i <= lastSize / 1024; i++) {
if (flag) {
break;
}
int read = bufferedInputStream.read(bys);
if (read != -1) {
bufferedOutputStream.write(bys, 0, read);
}
}
}else{
System.out.println("传输完成");
}
}
bufferedInputStream.close();
bufferedOutputStream.close();
System.gc();
System.runFinalization();
return true;
}
public static void main(String[] args) throws IOException {
SegmentedReadFile segmentedReadFile = new SegmentedReadFile();
segmentedReadFile.setDaemon(true);
segmentedReadFile.start();
boolean test = segmentedReadFile.test("G:/360安全浏览器下载安装包/tim_pc.exe", "G:/360安全浏览器下载安装包/tim_pc1.exe");
if (!test) {
System.out.println("传输失败");
}
}
}
7.重定向输出记录错误日志文件
public classRedirect1 {public static voidmain(String[] args) throws FileNotFoundException {
String str="hello world";
PrintStream printStream= new PrintStream("y.txt");
//可以不关闭,自动会刷新缓存
printStream.print(str);
}
8.字节字符转换流
public static voidmain(String[] args) throws IOException {//方式一
FileInputStream fileInputStream = new FileInputStream("1.txt");//不乱码的前提是知道编码,或者是unicode码的\\u方式写的
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,"utf-8");
BufferedReader bufferedReader= newBufferedReader(inputStreamReader);//java内存中是使用unicode码保存的
String readLine =bufferedReader.readLine();
System.out.println(readLine);if(bufferedReader!=null){
bufferedReader.close();
}if(inputStreamReader!=null){
inputStreamReader.close();
}if(fileInputStream!=null){
fileInputStream.close();
}
FileOutputStream fileOutputStream= new FileOutputStream("3.txt");
OutputStreamWriter outputStreamWriter= new OutputStreamWriter(fileOutputStream,"gbk");
BufferedWriter bufferedWriter= newBufferedWriter(outputStreamWriter);
bufferedWriter.write(readLine);if(bufferedWriter!=null){
bufferedWriter.close();
}if(outputStreamWriter!=null){
outputStreamWriter.close();
}if(fileOutputStream!=null){
fileOutputStream.close();
}
FileInputStream fileInputStream1= new FileInputStream("3.txt");//按指定解码然后按unicode保存
InputStreamReader inputStreamReader1 = new InputStreamReader(fileInputStream1,"gbk");
BufferedReader bufferedReader1= newBufferedReader(inputStreamReader1);
String readLine1=bufferedReader1.readLine();//将unicode码有转换成了工作空间相应的编码
System.out.println(readLine1);if(bufferedReader1!=null){
bufferedReader1.close();
}if(inputStreamReader1!=null){
inputStreamReader1.close();
}if(fileInputStream1!=null){
fileInputStream1.close();
}//方式二
ByteArrayOutputStream byteArrayOutputStream = newByteArrayOutputStream();
byteArrayOutputStream.write(readLine1.getBytes());//因为我的工作空间是utf-8的
String string = byteArrayOutputStream.toString("utf-8");
byteArrayOutputStream.close();
System.out.println(string);
FileInputStream fileInputStream2= new FileInputStream("3.txt");
ByteArrayOutputStream byteArrayOutputStream2= newByteArrayOutputStream();byte [] bs =new byte [1024];int len =0;while((len=fileInputStream2.read(bs))!=-1){
byteArrayOutputStream2.write(bs,0, len);
}//不会乱码
String string2 = byteArrayOutputStream2.toString("gbk");
fileInputStream2.close();
byteArrayOutputStream2.close();
System.out.println(string2);//readLine.getBytes(charset)//Charset.forName("UTF-8").encode(str)
}
9.其他一些流
SequenceInputStream 合并多个流文件SequenceInputStream(Enumeration extends InputStream> e)
PrintWriter 与PrintStream 差不多
PipedWriter是向与其它线程共用的管道中写入数据
CharArrayWriter、StringWriter是两种基本的介质流,它们分别向Char数组、String中写入数据
DataOutputStream 保存相应的数据,按保存的顺序读取
ZipOutputStream 压缩流批量压缩(文件夹)可以使用这个方法putNextEntry(ZipEntry e),ZipEntry(String name)使用指定名称创建新的 ZIP 条目。
ZipInputStream 解压流
public classZipInputStreamDemo2 {public static voidmain(String[] args) throws IOException {
File file= new File("d:" + File.separator + "zipFile.zip");
File outFile= null;
ZipFile zipFile= newZipFile(file);
ZipInputStream zipInput= new ZipInputStream(newFileInputStream(file));
ZipEntry entry= null;
InputStream input= null;
OutputStream output= null;while ((entry = zipInput.getNextEntry()) != null) {
System.out.println("解压缩" + entry.getName() + "文件");
outFile= new File("d:" + File.separator +entry.getName());if (!outFile.getParentFile().exists()) {
outFile.getParentFile().mkdir();
}if (!outFile.exists()) {
outFile.createNewFile();
}
input=zipFile.getInputStream(entry);
output= newFileOutputStream(outFile);int temp = 0;while ((temp = input.read()) != -1) {
output.write(temp);
}
input.close();
output.close();
}
}
}
//多个文件进行压缩
public classZipOutputStreamDemo2 {public static voidmain(String[] args) throws IOException {//要被压缩的文件夹
File file = new File("d:" + File.separator + "temp");
File zipFile= new File("d:" + File.separator + "zipFile.zip");
InputStream input= null;
ZipOutputStream zipOut= new ZipOutputStream(newFileOutputStream(zipFile));
zipOut.setComment("hello");if(file.isDirectory()) {
File[] files=file.listFiles();for (int i = 0; i < files.length; ++i) {
input=new FileInputStream(files[i]);
zipOut.putNextEntry(new ZipEntry(file.getName()+ File.separator +files[i].getName()));int temp = 0;while ((temp = input.read()) != -1) {
zipOut.write(temp);
}
input.close();
}
}
}
}