文件和文件流

文件和文件流文件和文件流1.File类Java.io.File类可以获取文件以及文件夹的一些基本的属性常用的方法文件名称,路径,大小,判断是否存在,删除,创建//创建一个文件对象(可以是文件,可以是文件夹) Filefile=newFile(“e:/java_text.txt”); //基本属性 booleancanWriter=file.canWrite(); …

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

文件和文件流

1. File类

Java.io.File类可以获取文件以及文件夹的一些基本的属性
常用的方法 文件名称,路径,大小,判断是否存在,删除,创建

// 创建一个文件对象(可以是文件,可以是文件夹)
		File file = new File("e:/java_text.txt");
		// 基本属性
		boolean canWriter = file.canWrite();
		System.out.println("是否可写:" + canWriter);
		boolean canRead = file.canRead();
		System.out.println("是否可读:" + canRead);
		long size = file.length(); // 常用
		System.out.println("文件大小:" + size);
		boolean isFile = file.isFile(); // 常用
		System.out.println("是否是文件:" + isFile);
		boolean isDirectory = file.isDirectory();
		System.out.println("是否是文件夹:" + isDirectory);
		String filename = file.getName(); // 常用
		System.out.println("文件的名称:" + filename);
		String absolutePath = file.getAbsolutePath(); // 常用
		System.out.println("文件的绝对路径:" + absolutePath);
		String filepath = file.getPath();
		System.out.println("文件的绝对路径:" + filepath);
		boolean isExists = file.exists(); // 常用
		System.out.println("是否存在:" + isExists);
		boolean isDelete = file.delete(); // 常用
		System.out.println("是否已经被删除:" + isDelete);
		boolean isCreate = file.createNewFile();
		System.out.println("创建了没有:" + isCreate);

Jetbrains全家桶1年46,售后保障稳定

File类的listFile获取文件夹下面的所有文件内容,可以通过递归调用的方法把某一个文件夹下的所有的文件查询出来

// 测试文件目录的属性(递归遍历文件夹中所有的文件信息)
	public static void testDirectoryDeme(File file) {
		if (file.isDirectory()) {
			File[] files = file.listFiles();
			System.out.println("文件夹"+file.getName()+"有"+files.length+"个文件");
			// 利用for遍历所有的文件
			for (int i = 0; i < files.length; i++) {
				File childFile = files[i];
				if (childFile.isFile()) {
					// 这是一个文件
					System.out.println("\t这是一个文件:" + childFile.getName());
				} else {
					// 文件夹:继续递归调用
					testDirectoryDeme(childFile);
				}
			}
		} else {
			// 这是一个文件
			System.out.println("\t这是一个文件:" + file.getName());
		}
	}

2. Files 和 paths是一个工具类,提供了对文件的基本功能的实现在java.nio包下面

文件的创建,删除,判断是否存在,移动,拷贝. 因为提供了静态的方法,所以不需要创建对象直接调用方法即可
// 如果文件不存在复制
if (!Files.exists(Paths.get("e:/a/cart1.jpg"))) {
	// java.nio.Files(文件的工具类) Paths(文件路径工具类)
	Files.copy(Paths.get("e:/cart1.jpg"), Paths.get("e:/a/cart1.jpg"));
}
Files.move(Paths.get("e:/a/cart1.jpg"), Paths.get("e:/a/b/cart1" + ((int) (Math.random() * 100)) + ".jpg"));
Files.delete(Paths.get("e:/cart1.jpg"));

3. 文件流

文件流的分类:
根据功能分为:输入流(读取文件) 和 输出流(写入文件)
根据操作内容:字符流(读取字符数组) 和 字节流(读取字节数组)
字节输入流,字节输出流,字符输入流,字符输出流
在这里插入图片描述
使用字节流实现文件的读取

//利用字节输入流实现文件的内容读取(inputStream 接口的  FileInputStream )
	public static void testInputStream() throws Exception{
		File file = new File("e:/a/file.txt");
		InputStream is = new FileInputStream(file);
		if(!file.exists()){
			System.out.println("文件不存在");
		}
		//开始读取文件
		byte[] temp_bytes = new byte[1024];
		int size = 0;  //用于记录读取文件的字节个数,如果没有读取任何的内容返回-1
		//因为文件不可能一次读取完毕,需要循环读取
		do{ 
			size =is.read(temp_bytes);
			if(size!=-1){
				String info = new String(temp_bytes,0,size,"GBK");
				System.out.println("读取的内容是:" + info);
			}
		}while(size !=-1); 
		//文件流是必须要关闭的(像水管子一样)
		is.close(); 

利用字节输出流实现文件的写入

//利用字节输出流实现文件内容的写入(OutputStream 接口的FileOutputStream)
	public static void testOuputStream() throws Exception{
		File file = new File("e:/a/file_new.txt");
		if(file.exists()){
			file.createNewFile();
		}
		//文件写入
		String info = "这就是我们要写入文件的内容";
		//创建文件写入对象
		OutputStream os = new FileOutputStream(file);
		os.write(info.getBytes());
		//写入完毕后,关闭
		os.flush();  //清空缓存区
		os.close();
	}

利用字节输入流和字节输出流实现文件的拷贝

//利用字节输入输入输出流,实现文件的复制,为了防止文件名称重复,需要对文件名称重命名
	public static void testCopy(String filepath) throws Exception
	{
		//创建文件对象
		File file = new File(filepath);
		//判断文件是否存在,且必须是一个文件而不能是一个文件夹
		if(!file.exists())
			throw new Exception("文件不存在");
		if(file.isDirectory())
			throw new Exception("只能拷贝文件,不能拷贝文件夹");
		//默认目标地址就是e:/a 文件夹
		
		//开始拷贝
		//创建一个文件输入流对象,读取文件的内容
		InputStream is = new FileInputStream(file);
		//创建一个文件输出流对象,写入文件的内容
		String filename = getFileName(file.getName());
		String targetpath="e:/a/"+filename;
		OutputStream os = new FileOutputStream(targetpath);
		//利用循环,边读取内容,边写入内容即可
		byte[] temp_info = new byte[1024];  //利用临时数组保存读取的内容
		int size = 0; //保存读取的字节个数,如果没有读取到内容返回-1
		do{
			//先读取
			size = is.read(temp_info);
			//判断是否读取到了文件的内容
			if(size!=-1){
				//写入文件
				os.write(temp_info, 0, size);
			}
		}while(size!=-1);
		
		//关闭,先关闭输出流,后关闭输入流
		os.flush();
		os.close();
		is.close();
	}
	//根据原有的文件名称获取新的文件名称
	public static String getFileName(String fileName){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
		//abc.mp4  ---abc_20190805164520.mp4
		//根据.分别获取文件名称和扩展名
		String[] name_infos = fileName.split("\\.");
		//获取当前日期的字符串
		Date date = new Date();
		String dateStr = sdf.format(date);
		 
		return name_infos[0]+"_"+dateStr+"."+name_infos[1];
	}

重点是熟练使用FileInputStream 和FileOutputStream 的使用

// 利用字节流复制某一个文件夹中的所有文件
	public static void testCopyDirectory() throws Exception {
		File file = new File("e:/file_source");
		// 实现复制
		// 创建文件输入输出流对象
		InputStream is = null;
		OutputStream os = null;
		try {
			// 遍历这个文件夹下的所有的文件信息
			File[] files = file.listFiles();
			for (int i = 0; i < files.length; i++) {
				File childFile = files[i];
				// 如果是一个文件就复制
				if (childFile.isFile()) {
					is = new FileInputStream(childFile);
					// 根据原有的文件名称获取新的文件名称
					String newFileName = getNewFileName(childFile.getName());
					os = new FileOutputStream("e:/a/b/" + newFileName);
					byte[] temp_info = new byte[1024];
					int size = -1;
					do {
						// 先读取
						size = is.read(temp_info);
						// 后写入(写入的内容多去取决于读取的内容多少)
						if (size != -1) {
							os.write(temp_info, 0, size);
						}
					} while (size != -1);
				}
			}
		} catch (Exception ex) {
			throw new Exception(ex);
		} finally {
			if (os != null)
				os.close();
			if (is != null)
				is.close();
		}
	}

	// 根据原有的文件名称,获取新的文件名称
	public static String getNewFileName(String oldFileName) {
		// oldname :上机作业.docx newnmae : 上机作业_20180222.docx;
		// 根据原有的文件名称获取文件名字和文件的类型
		int index = oldFileName.lastIndexOf(".");
		if (index == -1) {
			return oldFileName;
		}
		// 获取文件名: 上机作业
		String name = oldFileName.substring(0, index);
		// 获取文件类型: docx
		String type = oldFileName.substring(index + 1);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
		Date date = new Date();
		String formatstr = sdf.format(date);
		// 上机作业_20180222.docx;
		return name + "_" + formatstr + "." + type;
	}

使用对象输入输出流实现对象的序列化和反序列化

public static void testObjectInputStream() throws Exception{
		File file = new File("e:/a/stu.txt");
		InputStream is = new FileInputStream(file);
		ObjectInputStream ois = new ObjectInputStream(is);
		List<Student>  stuList= (List<Student>)ois.readObject(); 
		ois.close();
		is.close();
		
		for(Student stu: stuList){
			System.out.println(stu);
		}
	}
	//对象序列化(实现JAVA对象的保存和读取 ObjectInputStream)
	public static void testObjectOutputStream()  throws Exception{
		Student stu3 = new Student("赵丽丽","女","河北廊坊");
		stuList.add(stu3);
		//把集合保存到文件中 
		File file = new File("e:/a/stu.txt");
		OutputStream os = new FileOutputStream(file);
		ObjectOutputStream oos = new ObjectOutputStream(os);
		oos.writeObject(stuList);
		oos.flush();
		oos.close();
		os.close();
		
	}

字符流的读取和写入(只能读取字符文件的信息)

//使用字符流读取文件
	public static void testReader() throws Exception{
		//创建文件对象
		File file = new File("e:/a/file.txt");
		//创建字符输入流对象
		Reader reader = new FileReader(file);
		//创建字符输出流对象
		File file2 = new File("e:/a/b/file_3.txt");
		Writer writer = new FileWriter(file2);
		char[] temp = new char[1000];
		int size =0;
		//通过循环边度编写
		do{
			size= reader.read(temp);  //读取字符内容
			if(size!=-1)
			{
				writer.write(temp, 0, size);
			}
		}while(size!=-1);
		//关闭
		writer.flush();
		writer.close();
		reader.close();
	}

释放资源的新方法

//新的关闭资源的方法
		//try(  定义必须要关闭的对象; ){}catch(Exception ex){}; 
		// 创建输出流对象
		try(	OutputStream os = new FileOutputStream(FILE_PATH);
				ObjectOutputStream oos = new ObjectOutputStream(os); ) {

			oos.writeObject(stuList);
		} catch (Exception e) {
			throw new Exception(e);
		} 

4. 线程的状态

初始状态(创建了对象)
可运行状态(调用了start方法)
运行状态(调用了run方法)
阻塞状态 (调用了seleep,join,wait方法)
终结状态 (运行完毕)
在这里插入图片描述

5. 线程的常用方法

Start() 启动方法 表示线程进入了可运行状态
Seleep(int) 随眠方法,当前线程进入阻塞状态,在一定时间以后苏醒
Join() 方法 被调用者优先执行,执行完毕后当前线程在执行(阻塞的的是当前线程)
Wait() 方法 当前线程进入阻塞状态,一直到对方唤醒自己才可以继续执行
notifyAll()唤醒被阻塞的线程
需要注意:wait(),notify()两个方法是Object类提供的

package com.xja.sxnd.filedemo;
public class ThreadDemo {

	public static void main(String[] args) {
		MyThread mt = new MyThread();
		MyRunable mr = new MyRunable();
		Thread thread = new Thread(mr);
		mt.start();
		thread.start();
		for(int i = 0;i< 50;i++){
			if(i == 20){
				try{
					//主线程执行到20的时候,先让第一个线程执行完毕,然后主线程在接着执行
				mt.join(); 
				}catch(Exception ex){
					ex.printStackTrace();
				}
			}
			System.out.println("主线程中的内容:" +i);
		}	
	}
}
class MyThread extends Thread
{ 
	@Override
	public void run() {
		 for(int i =0;i< 50;i++){
			 try{
			 if(i==20)
				 Thread.sleep(500); //停止运行0.5秒,时间到了以后自动执行
			 }catch(Exception ex){
				 ex.printStackTrace();
			 }
			 System.out.println("第一个线程的对象:" +i);
		 }
	}
}
class MyRunable implements Runnable{
	@Override
	public void run() {
		 for(int i =0;i< 50;i++){
			 System.out.println("第二个线程的对象:"+i);
		 }
	}	
}

.

6. 线程的死锁

如果两个线程同时调用对方线程的JOIN方法,互相希望对方先运行就会出现死锁的问题

public class MyRunnable implements Runnable {
	public Thread myThread;
	@Override
	public void run() {
		try {
			for (int i = 0; i < 100; i++) { 
				Thread.sleep(10); 
				if(i == 5){
					System.out.println("MyRunnable运行到了5,也休息,让Thread先走");
					myThread.join();
				}
				System.out.println("第二个线程:" + i);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	} 
}

public class MyThread extends Thread {
	public Thread myRun;
	@Override
	public void run() {
		try {
			for (int i = 0; i < 10; i++) { 
				Thread.sleep(10); 
				
				if(i==5){
					System.out.println("Thread 运行到了5 就需要对方先走");
					myRun.join();
				}
				System.out.println("第一个线程的内容:" + i);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	} 
}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try { 
			// 创建一个线程对象
			MyThread myThread = new MyThread();
			// 创建第二个线程
			MyRunnable myRunn = new MyRunnable(); 
			Thread thread = new Thread(myRunn); 
			// 启动线程 启动线程不能直接调用run 只能调用start 
			myThread.myRun = thread;
			myRunn.myThread = myThread;
			 
			myThread.start();
			thread.start();
}

7. 线程的同步

StringBuilder和StringBuffer ArrayList 和vector HashMap 和HashTable

当两个线程同时操作同一个对象的时候,因为两个线程互相影响对方的结果,导致数据不统一,这种现象称之为线程不同步
例如:银行卡存取钱的问题。(两种方式操作一个账户)

public class Card {
	private int balance =500;
	public void takeMoney(int money){
		if(balance>money){
			System.out.println("取钱之前的余额:" + balance); 
			int temp_balance = balance - money;
			balance = temp_balance;
			System.out.println("取钱之后的余额:" + balance);
		}
	}
	public void saveMoney(int money){
		System.out.println("存钱之前的余额:" + balance); 
		int temp_balance = balance + money;
		balance = temp_balance;
		System.out.println("存钱之后的余额:" + balance);	
	}
}
 
public class ThreadDemo {
	public static void main(String[] args) {
		Card card = new Card();
		MyThread mt = new MyThread(card);
		MyRunable mr = new MyRunable(card);
		Thread thread = new Thread(mr);
		mt.start();
		thread.start();
		System.out.println("程序结束");
	}
}
class MyThread extends Thread
{ 
	private Card card;
	public MyThread(Card card){
		this.card = card;
	}
	@Override
	public void run() { 
		 for(int i =0;i< 10;i++){ 
			 card.takeMoney(50);
		 } 
	} 
}
class MyRunable implements Runnable{
	private Card card;
	public MyRunable(Card card){
		this.card = card;
	}
	@Override
	public void run() { 
		 for(int i =0;i< 10;i++){ 
			card.saveMoney(50);
		 } 
	}	
}

通过synchronized关键字修饰方法就是线程同步的方法,线程同步的方法要求同一个对象同时只能调用一个方法

public class Card {
	private int balance = 500;
	public void takeMoney(int money) {
		synchronized (this) {
			if (balance > money) {
				System.out.println("取钱之前的余额:" + balance);
				int temp_balance = balance - money;
				balance = temp_balance;
				System.out.println("取钱之后的余额:" + balance);
			}
		}
	}

	public void saveMoney(int money) {
		synchronized (this) {
			System.out.println("存钱之前的余额:" + balance);
			int temp_balance = balance + money;
			balance = temp_balance;
			System.out.println("存钱之后的余额:" + balance);
		}
	}
}

8. 线程的经典案例(生产者和消费者)

public class Card {
	private int balance = 500;

	public synchronized void takeMoney(int money) throws Exception {
		if (balance -money<0) {
			System.out.println("家里没有钱了,需要减少消费");
			this.wait();
			return;
		}
		System.out.println("取钱之前的余额:" + balance);
		int temp_balance = balance - money;
		balance = temp_balance;
		System.out.println("取钱之后的余额:" + balance);

		// 一旦我花费了钱,就可以让生成者继续生成
		this.notify();
	}

	public synchronized void saveMoney(int money) throws Exception {
		// 如果挣钱的足够,则需要休息,让消费者消费
		if (balance > 700) {
			System.out.println("钱以够多了,可以休息一下");
			this.wait();
			return;
		}
		System.out.println("存钱之前的余额:" + balance);
		int temp_balance = balance + money;
		balance = temp_balance;
		System.out.println("存钱之后的余额:" + balance);
		// 一旦有钱就可以让消费者消费
		this.notifyAll();
	}
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/206722.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • jenkins拉取gitlab代码_git强制覆盖远程仓库代码

    jenkins拉取gitlab代码_git强制覆盖远程仓库代码前言python自动化的脚本开发完成后需提交到git代码仓库,接下来就是用Jenkins拉取代码去构建自动化代码了新建项目打开Jenkins新建一个自由风格的项目源码管理Repository

  • 金九银十准备季:Java IO流面试题(含答案)「建议收藏」

    金九银十准备季:Java IO流面试题(含答案)「建议收藏」前言本题集列举了众多IT公司面试真题,对应聘Java程序员职位的常见考点和知识体系都进行的分类和归纳整理。本题集适合应聘Java和JavaEE职位的程序员作为面试复习、学习和强化的资料,也适合其他程序员作为拓展读物进行阅读。本题集包含了常见的算法、面试题,也包含了新的高级技术,比如:微服务架构等技术的面试题目。本题集非常全面,对于工作1-5年左右的java程序员面试有非常好的指导作用。大家也可以访问(直接在线观看最新版的面试题):Java考试_Java笔试题机试题真题讲解_JavaWeb

  • git拉取代码密码错误_idea提交git

    git拉取代码密码错误_idea提交gitgit提交代码1:一定要先pull,(在本地建立仓库)eclipse中点击file找到term中的pull,同步拉取远程代码,idea中tomcat旁边斜向下箭头,拉取,首次拉取要输入用户名密码,2:提交到本地仓库commit,并填写提交备注,方便查找,3:push推送远程分支,提交到git分支。常见的pull失败:冲突-多个人修改同一个文件,别人修改后自己也修改导致拉取失败,解决冲突…

    2022年10月21日
  • Boost.Lockfree无锁结构

    Boost.Lockfree无锁结构[译]https://beta.boost.org/doc/libs/1_72_0/doc/html/lockfree.html boost.Lockfree无锁结构学习

  • oracle删除主键索引的sql语句_oracle主键索引和普通索引

    oracle删除主键索引的sql语句_oracle主键索引和普通索引–根据索引名,查询表索引字段select*fromuser_ind_columnswhereindex_name=’索引名’;–根据表名,查询一张表的索引select*fromuser_indexeswheretable_name=’表名’;–根据索引名,查询属于哪张表select*fromall_indexeswhereindex_name=’IN…

  • fromopen函数通达信_precision函数

    fromopen函数通达信_precision函数apply及applyIf方法都是用于实现把一个对象中的属性应用于另外一个对象中,相当于属性拷贝。  不同的是apply将会覆盖目标对象中的属性,而applyIf只拷贝目标对象中没有而源对象中有的属性。 apply方法的签名为“apply(Objectobj,Objectconfig,Objectdefaults):Object”, 该方法包含三个参数…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号