javaIO流学习笔记02

x33g5p2x  于2021-11-26 转载在 Java  
字(6.8k)|赞(0)|评价(0)|浏览(484)

首先说一下昨天的小问题:

那就是为什么总是第一个人再抢票?为什么总是打印输出了第一个.start的线程,但是明明线程是正常运转的:我们昨天完善的最好的一次就是使用 List<Integer> list = new ArrayList<>();,用这个数组来存放获取到的票就可以很好的显示结果:

而且从下面这个方法可以将 synchronized(ob)改成 synchronized(this)即使前面输出错误最后的list依然可以存放正确,说明问题的原因并不是在 synchronized()上面:

  1. package 任务十__多线程.售票;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. public class TestDemo {
  5. //定义售票线程类(也就是窗口)
  6. public static class Station extends Thread{
  7. //构造方法给线程名字赋值
  8. public Station(String name) {
  9. super(name);
  10. }
  11. //票数要静态定义
  12. static int tick=50;
  13. //静态钥匙
  14. static Object ob ="key"; //值是任意的
  15. //重写run方法,实现售票操作
  16. @Override
  17. public void run() {
  18. List<Integer> list = new ArrayList<>();
  19. while (tick>0) {
  20. synchronized(ob) { //必须使用一个同步锁,进去的人会把钥匙拿在手上,出来后才能交出钥匙
  21. if (tick>0) {
  22. System.out.printf("%s卖出了第%d张票 \n",getName(),tick);
  23. list.add(tick);
  24. tick--;
  25. }else {
  26. System.out.printf("%s:票已售空 \n",getName());
  27. }
  28. }
  29. try {
  30. sleep((int)(Math.random()*3000)+1); //随机休息1-3000ms
  31. }catch (InterruptedException e) {
  32. e.printStackTrace();
  33. }
  34. }
  35. System.out.printf("%s 销售情况: %s \n",getName(),list.toString());
  36. }
  37. }
  38. public static void main(String[] args) {
  39. //实例化站台对象,并为每一个站台取名字(8个线程窗口一起卖5张票)
  40. for (int i=1; i<=8; i++) {
  41. String sName="窗口" + String.valueOf(i);
  42. Station Station = new Station(sName);
  43. Station.start();
  44. }
  45. }
  46. }

然后我们想一下为什么,通过上面这个成功例子映射一下,这个例子比其他代码多了一个什么步骤?那就是存放票,可以看的更清楚,所以我们尝试再锁 synchronized()之前加入一行代码: System.out.println(getName()+"正在卖票");

  1. package 任务十__多线程.售票;
  2. /** * @author ${范涛之} * @Description * @create 2021-11-24 23:43 */
  3. class SaleThread extends Thread {
  4. /** * 使用静态成员变量作为100张票的保存变量,是一个共享资源。 */
  5. private static int tickets = 20;
  6. public SaleThread(String name){
  7. super(name);
  8. }
  9. @Override
  10. public void run() {
  11. // 完成售票过程
  12. while (true) {
  13. System.out.println(getName()+"正在卖票");
  14. synchronized (this) {
  15. try {
  16. Thread.sleep(100);
  17. } catch (InterruptedException e) {
  18. e.printStackTrace();
  19. }
  20. if (tickets > 0) {
  21. System.out.println(Thread.currentThread().getName() + "售出了" + tickets + "张票");
  22. tickets--;
  23. } else {
  24. System.out.println(Thread.currentThread().getName() + "售罄!!!");
  25. break;
  26. }
  27. }
  28. }
  29. }
  30. }
  31. public class Demo {
  32. public static void main(String[] args) {
  33. new SaleThread("范涛之").start();
  34. new SaleThread("张荣康").start();
  35. new SaleThread("秦舒下").start();
  36. }
  37. }

运行结果:

为什么要加这句话才可以输出成功?答案:

因为线程即使执行完System.out.println(getName() + “抢到了第” + ticket + “火车票”);但是还没来得及打印,就被别的线程抢走了,等别的线程打印了,他可能抢到执行时间,才会打印,所以,在上面加一行System.out.println(getName() + “正在抢票…”);系统打印就能正确显示。
程序并没有错误,只是System.out.println跟不上线程的速度。

也就是说为什么总是在打印第一个人,因为的就是线程来不及去打印其他人!

分割线·····················································································

JavaIO流:

怎样递归一个盘下面的所有目录:

思路:1:首先通过过file.listFiles()方法获取目录下的所有文件(包含子目录下的所有文件),得到files[]数组,后续的增强for循环中就是通过比较数组中的值是文件还是目录

2:然后遍历得到的所有文件

3:通过isFile(文件)和isDirectory(文件夹)方法来判断读取的是文件还是文件夹,如果得到的是文件夹,就递归调用test()方法,如果得到的是文件,就将其加入fileList中,

4:最后测试的时候遍历fileList下的所有文件,来验证读取数据的准确性。

代码实现:

1:首先新建一个文件类型的集合:

  1. List<File> fileList = new ArrayList<File>();

然后引入File,并且创建file.listFiles():

  1. File file = new File(fileDir);
  2. File[] files = file.listFiles();

然后先判断files是否为空,要是空直接返回:

  1. if (files==null){
  2. return;
  3. }

接下来判断是文件还是目录:目录则递归,文件则添加:

  1. for (File f :files){
  2. if (f.isFile()){
  3. fileList.add(f);
  4. }else if (f.isDirectory()){
  5. System.out.println(f.getAbsolutePath());
  6. test(f.getAbsolutePath()); //递归调用
  7. }
  8. }

遍历集合打印:

  1. for (File f1 :fileList){
  2. System.out.println(f1.getName());
  3. }

主方法传入值:

  1. public static void main(String[] args) {
  2. test("C:/");
  3. }

全部代码:

  1. package 任务11IO流;
  2. import java.io.File;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. /** * @author ${范涛之} * @Description * @create 2021-11-25 12:31 */
  6. public class Test5 {
  7. private static void test(String fileDir){
  8. List<File> fileList = new ArrayList<File>();
  9. File file = new File(fileDir);
  10. File[] files = file.listFiles();
  11. if (files==null){
  12. return;
  13. }
  14. for (File f :files){
  15. if (f.isFile()){
  16. fileList.add(f);
  17. }else if (f.isDirectory()){
  18. System.out.println(f.getAbsolutePath());
  19. test(f.getAbsolutePath()); //递归调用
  20. }
  21. }
  22. for (File f1 :fileList){
  23. System.out.println(f1.getName());
  24. }
  25. }
  26. public static void main(String[] args) {
  27. test("C:/");
  28. }
  29. }

运行截图:

怎样使用java复制文件:一共有四种方法:

1. 使用FileStreams复制:是最经典的方式将一个文件的内容复制到另一个文件中。 使用FileInputStream读取文件A的字节,使用FileOutputStream写入到文件B。 这是第一个方法的代码:(字节流)

  1. package 任务11IO流;
  2. import java.io.*;
  3. public class Test6{
  4. private static void copyFileUsingFileStreams(String source, String dest) throws IOException {
  5. InputStream input = null;
  6. OutputStream output = null;
  7. try {
  8. input = new FileInputStream(source);
  9. output = new FileOutputStream(dest);
  10. byte[] buf = new byte[1024];
  11. int bytesRead;
  12. while ((bytesRead = input.read(buf))>0){
  13. output.write(buf,0,bytesRead);
  14. }
  15. }finally {
  16. input.close();
  17. output.close();
  18. }
  19. }
  20. public static void main(String[] args) throws IOException {
  21. copyFileUsingFileStreams("H:\\bilbil\\07.mp4","F:\\shipin\\007.mp4");
  22. }
  23. }

运行结果:

首先讲解一下一些参数:

  • source和dest分别是自定义的源文件位置和待复制的位置

  • output.write(buf,0,bytesRead);:其实这里也就是FileOutputStream.write:后面的三个参数依次是:byte[] b, int off, int len,也就是将 len字节从位于偏移量 off的指定字节数组写入此文件输出流。偏移量也就是相对位置的意思。

  • input.read同上等于FileInputStream.read:read(byte[] b, int off, int len) 的意思就是从该输入流读取最多 len字节的数据为字节数组。

第二种方式:NIO:使用FileChannel复制:Java NIO包括transferFrom方法,根据文档应该比文件流复制的速度更快。

  1. package 任务11IO流;
  2. import java.io.FileInputStream;
  3. import java.io.FileNotFoundException;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.nio.channels.FileChannel;
  7. /** * @author ${范涛之} * @Description * @create 2021-11-25 20:56 */
  8. public class Test7 {
  9. private static void copyFileUsingFileChannels(String sourse,String dest) throws IOException {
  10. FileChannel inputChannel = null;
  11. FileChannel outputChannel = null;
  12. try {
  13. inputChannel = new FileInputStream(sourse).getChannel();
  14. outputChannel = new FileOutputStream(dest).getChannel();
  15. outputChannel.transferFrom(inputChannel,0,inputChannel.size());
  16. }finally {
  17. inputChannel.close();
  18. outputChannel.close();
  19. }
  20. }
  21. public static void main(String[] args) throws IOException {
  22. copyFileUsingFileChannels("H:\\bilbil\\毒液2.mp4","F:\\shipin\\复制版毒液2.mp4");
  23. }
  24. }

运行结果:

这里说一下字符流:字符流只能读取文本不可以读取视频!

字符流:

  1. package 任务11IO流;
  2. import java.io.*;
  3. /** * @author ${范涛之} * @Description * @create 2021-11-25 21:48 */
  4. public class Test8 {
  5. private static void copyFileUsingFileStreams(String source, String dest) throws IOException {
  6. FileReader reader = null;
  7. FileWriter writer = null;
  8. try {
  9. reader = new FileReader(source);
  10. writer = new FileWriter(dest);
  11. char[] chs = new char[1024];
  12. int bytesRead;
  13. while ((bytesRead = reader.read(chs)) > 0) {
  14. writer.write(chs, 0, bytesRead);
  15. }
  16. } finally {
  17. reader.close();
  18. writer.close();
  19. }
  20. }
  21. public static void main(String[] args) throws IOException {
  22. copyFileUsingFileStreams("H:\\bilbil\\毒液2.mp4","F:\\shipin\\哈哈哈毒液2.mp4");
  23. }
  24. }

这样的代码是错误的,因为只能复制文件文本:

  1. package 任务11IO流;
  2. import java.io.*;
  3. /** * @author ${范涛之} * @Description * @create 2021-11-25 21:48 */
  4. public class Test8 {
  5. private static void copyFileUsingFileStreams(String source, String dest) throws IOException {
  6. FileReader reader = null;
  7. FileWriter writer = null;
  8. try {
  9. reader = new FileReader(source);
  10. writer = new FileWriter(dest);
  11. char[] chs = new char[1024];
  12. int bytesRead;
  13. while ((bytesRead = reader.read(chs)) > 0) {
  14. writer.write(chs, 0, bytesRead);
  15. }
  16. } finally {
  17. reader.close();
  18. writer.close();
  19. }
  20. }
  21. public static void main(String[] args) throws IOException {
  22. copyFileUsingFileStreams("H:\\bilbil\\我爱佳佳.txt","F:\\shipin\\我超级爱佳佳.txt");
  23. }
  24. }

运行结果:

相关文章

最新文章

更多

目录