【问题标题】:File writing and reading objects using Threads使用线程写入和读取对象的文件
【发布时间】:2012-05-16 09:38:37
【问题描述】:

我有一个主线程,我们从它启动两个后续线程,分别执行文件写入和文件读取操作。我有另一个名为 orderDetails 的类,它具有属性及其 getter 和 setter。当前程序以这样一种方式运行,它会将对象列表一次性写入文件并读回。

问题:我需要将对象(cust1)的内容写入文件并同时从文件中读取。这必须对所有对象(cust1,cust2)执行指定的。提出解决此问题的可能方法。

主类

public class MainThread  {
         public static void main(String[] args) throws InterruptedException {
              Thread1 td1=new Thread1();
              Thread2 td2=new Thread2();
              Thread t1=new Thread(td1);
              Thread t2=new Thread(td2);
              t1.start();
              t1.sleep(100);
              t2.start();
        }
    }

orderDetails 类 - 一个普通的 pojo 类

 public class orderDetails {
        private String custName;
        private double advancePaid;
        private int mobileModel;
        private boolean replacement;
        private String problemFaced;
        private boolean softwareRequirement;
       public orderDetails(String custName, double advancePaid, int mobileModel,
                boolean replacement, String problemFaced,
                boolean softwareRequirement) {
            super();
            this.custName = custName;
            this.advancePaid = advancePaid;
            this.mobileModel = mobileModel;
            this.replacement = replacement;
            this.problemFaced = problemFaced;
            this.softwareRequirement = softwareRequirement;
        } 
        public boolean isSoftwareRequirement() {
            return softwareRequirement;
        }
        public void setSoftwareRequirement(boolean softwareRequirement) {
            this.softwareRequirement = softwareRequirement;
        }
        public int getMobileModel() {
            return mobileModel;
        }
        public void setMobileModel(int mobileModel) {
            this.mobileModel = mobileModel;
        }
        public String getProblemFaced() {
            return problemFaced;
        }
        public void setProblemFaced(String problemFaced) {
            this.problemFaced = problemFaced;
        }
        public boolean isReplacement() {
            return replacement;
        }
        public void setReplacement(boolean replacement) {
            this.replacement = replacement;
        }
        public double getAdvancePaid() {
            return advancePaid;
        }
        public void setAdvancePaid(double advancePaid) {
            this.advancePaid = advancePaid;
        }
        public String getCustName() {
            return custName;
        }
        public void setCustName(String custName) {
            this.custName = custName;
        }

    }

文件写入-将属性写入文件

 public class FileWriting implements Runnable {
        orderDetails cust1=new orderDetails("vid",2000.00,2543,true,"display",false);
        orderDetails cust2=new orderDetails("kesav",8000.00,7845,false,"battery",true);
        ArrayList<orderDetails> orderArr=new ArrayList<orderDetails>();
         orderDetails obj;
                public void run() {
            orderArr.add(cust1);
            orderArr.add(cust2);
             try {
                for(orderDetails obj:orderArr)
                {
                fileOperations(obj);
                }
            }
                catch (IOException e) {
                    e.printStackTrace();
            }
        }

        public void fileOperations(orderDetails obj) throws IOException{
            File f= new File("C:\\Users\\311518\\Desktop\\threadtest2.txt");
            Calendar calNow = Calendar.getInstance();
            Calendar orderDate;
            SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
            FileWriter fstream;
              if(f.exists()){
                  //append mode
             fstream = new FileWriter(f,true);
              }
              else
              {
                  // to open a new file
              f.createNewFile();
                    // write mode
             fstream = new FileWriter(f,false);
              }
              BufferedWriter out = new BufferedWriter(fstream);
                     out.write(obj.getCustName()+" "+obj.getMobileModel()+" "+obj.getProblemFaced()+" "+obj.getAdvancePaid()+" "+obj.isReplacement()+" "+obj.isSoftwareRequirement());  
                     double balanceAmt=obj.getAdvancePaid()-200;
                     out.write(" "+balanceAmt); 
                     orderDate = (Calendar) calNow.clone();
                     out.write(" "+formatter.format(orderDate.getTime()));
                     orderDate.add(Calendar.DAY_OF_YEAR, + 10);
                     out.write(" "+formatter.format(orderDate.getTime()));
                     out.newLine();
                 out.close();
        }
     }

文件读取类-从文件中读取属性

 public class FileReading implements Runnable{
        File f= new File("C:\\Users\\311518\\Desktop\\threadtest2.txt");
        public void run() {
            try {
                readingText();
                System.out.println("Thanks for ur order");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        public void readingText() throws IOException{
            String [] temp = null;
            FileReader fr = new FileReader(f); 
            BufferedReader br = new BufferedReader(fr); 
            String s; 
            System.out.println("--------ORDER DETAILS------");
             System.out.println("Name Model Adv Prob Replacement S/w Bal OrderDate Deliverdate ");
                while((s = br.readLine()) != null) { 
                                      //display ordered details
                      temp = s.toString().split("\n");
                      for(int i=0;i<temp.length;i++){
                    System.out.println(temp[i]);
                      }
        }

    }
    }

【问题讨论】:

  • 我认为您提供了太多有关当前代码的详细信息(但我认为太多总比不够好)。这似乎是一个奇怪的用例……您需要保留文件数据吗?如果没有,似乎您可以使用命名(或非)管道而不是文件。
  • 我需要一个一致的数据存储,也只是一个文件。

标签: java multithreading file-io


【解决方案1】:

你可以尝试使用一个普通的锁对象,在你写的时候给它加个锁,然后等写完再读。 示例:

写:

for(orderDetails obj:orderArr)
{
    synchronized(FileWriting.class)
    {
        fileOperations(obj);
    }
    Thread.yield();
}   

阅读:

synchronized(FileWriting.class) {
    readingText();
    Thread.yield();
}

也许您还应该在循环中添加读取,并让写入器在写入完成时发出信号,以便读取器可以停止。

【讨论】:

  • 我仍然不知道如何实现此代码,您可以详细说明一下吗?
【解决方案2】:

我认为 wait() 和 notify() 的完美案例。

文件编写

  1. 构建订单详细信息列表
  2. 在此同步
  3. 将订单详细信息写入文件
  4. 通知()
  5. 结束同步块

文件读取

  1. 文件写入同步
  2. 从文件中读取
  3. 等待()
  4. 在有利于您的订单条件的情况下执行此操作
  5. 结束同步块

【讨论】:

    【解决方案3】:

    您可以像下面的代码一样执行上述操作。使用wait()notify()完美使用生产者消费者线程。

    FileOperator.java

    public class FileOperator {
        File file = new File("D:\\Personal\\MyProjects\\File\\file.txt");
    
        BufferedWriter bw;
        BufferedReader br;
        boolean isWriteComplete = false;
    
        public FileOperator() throws IOException {
            if(!file.exists())
                file.createNewFile();
            bw = new BufferedWriter(new FileWriter(file));
            br = new BufferedReader(new FileReader(file));
    
        }
    
        public void writeInFile(String str) throws IOException{
            bw.write(str);
            bw.newLine();
            bw.flush();
        }
    
        public String readFromFile() throws IOException{
            return br.readLine();
        }
    }
    

    这是我们的 FileReaderWriterDemo.java

    class ThreadReader implements Runnable{
        FileOperator fo;
    
        public ThreadReader(FileOperator fo) {
            super();
            this.fo = fo;
        }
    
        @Override
        public void run() {
            synchronized (fo) {
                if(!fo.isWriteComplete){
                    try {
                        fo.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("--------ORDER DETAILS------");
                try {
                    System.out.println(fo.readFromFile());
                } catch (IOException e) {
                    e.printStackTrace();
                }
                fo.notify();
            }
        }
    }
    
    class ThreadWriter implements Runnable{
        FileOperator fo;
    
        public ThreadWriter(FileOperator fo) {
            super();
            this.fo = fo;
        }
        @Override
        public void run() {
            synchronized (fo) {
                System.out.println("Going to write...");
                try {
                    fo.writeInFile("OrderNo:1 | advancePaid: 2000 | custName: Mr.XXX | mobileModel: Nokia");
                } catch (IOException e) {
                    e.printStackTrace();
                }
                fo.isWriteComplete = true;
                fo.notify();
            }
        }
    
    }
    
    public class FileReaderWriterDemo {
    
        public static void main(String[] args) {
            FileOperator fop = null;
            try {
                fop = new FileOperator();
            } catch (IOException e) {
                e.printStackTrace();
            }
            Thread tr = new Thread(new ThreadWriter(fop));
            tr.start();
    
            Thread tw = new Thread(new ThreadReader(fop));
            tw.start();
        }
    
    }
    

    控制台输出:

    要写了

    --------订单详情------

    订单号:1 |预付:2000 |客户姓名:XXX先生 |手机型号:诺基亚

    【讨论】:

      【解决方案4】:

      请找到下面的代码示例......

      import java.io.File;
      import java.io.FileInputStream;
      import java.io.FileOutputStream;
      import java.io.RandomAccessFile;
      
      class MyBuffer{
          transient byte[] bytes = null;
          public int bytesTransmitted = 0;
          private int bufferedBytes = 0;
          public static boolean isWriting = false;
          public static boolean readComplete = false;
          MyBuffer(File srcFile,File desFile){
              try {
                  if(!desFile.exists()){desFile.createNewFile();}
      
                  ReadThread  readThrd  = new ReadThread  (this,new RandomAccessFile(srcFile,"r"),"read");
      //          ReadThread  readThrd  = new ReadThread  (this,new FileInputStream(srcFile),"read");
      //          WriteThread writeThrd = new WriteThread (this,new RandomAccessFile(desFile,"rw"),"write");
                  WriteThread writeThrd = new WriteThread (this,new FileOutputStream(desFile),"write");
              } catch (Exception e) {
                  e.printStackTrace();
              }       
          }
          public void clearBytes() {
              this.bytes = null;
              this.bytesTransmitted+=this.bufferedBytes;
              this.bufferedBytes=0;
              MyBuffer.isWriting = false;
      
          }
          public byte[] getBytes() {
              return this.bytes;
          }
          public void setBytes(byte[] bytes) {
              if(bytes!=null){
                  if(this.bytes!=null){
                      byte[] tempByte = new byte[this.bytes.length+bytes.length];
                      System.arraycopy(this.bytes, 0, tempByte, 0, this.bytes.length);
                      System.arraycopy(bytes, 0, tempByte, this.bytes.length, bytes.length);
                      this.bytes = tempByte;
                  }else{
                      this.bytes = bytes;
                  }
                  this.bufferedBytes+=bytes.length;
              }
          }
      
      
      }
      class ReadStreamThread implements Runnable{
          @Override
          public void run() {
              // TODO Auto-generated method stub
      
          }
      }
      class ReadThread implements Runnable{
          private Thread t;
          private RandomAccessFile file=null;
          private FileInputStream fis=null;
          private MyBuffer buffer;
      
          ReadThread(MyBuffer obj,RandomAccessFile readFile,String threadName) {
              // TODO Auto-generated constructor stub
              this.t = new Thread(this,threadName);
              this.file = readFile;
              this.buffer = obj;
              this.t.start();
          }
          ReadThread(MyBuffer obj,FileInputStream readFis,String threadName) {
              // TODO Auto-generated constructor stub
              this.t = new Thread(this,threadName);
              this.fis = readFis;
              this.buffer = obj;
              this.t.start();
          }
          @Override
          public void run() {
              // TODO Auto-generated method stub
              try {
                  while(true){
                      if(!MyBuffer.isWriting){
                          byte[] b = new byte[10];
                          if(file!=null){
                              if(this.file.length()<=this.buffer.bytesTransmitted){
                                  this.buffer.setBytes(null);
                                  this.buffer.readComplete = true;
                                  break;
                              }
                              this.file.read(b);
                              this.buffer.setBytes(b);
                          }else if(fis!=null){
                              if(this.fis.available()<=this.buffer.bytesTransmitted){
                                  this.buffer.setBytes(null);
                                  break;
                              }
                              this.fis.read(b);
                              this.buffer.setBytes(b);
                          }
                      }
                  }
              } catch (Exception e) {
                  // TODO: handle exception
                  e.printStackTrace();
              }
      
          }
      }
      class WriteThread implements Runnable{
          private Thread t;
          private RandomAccessFile file=null;
          private FileOutputStream fos=null;
          private MyBuffer buffer;
      
          WriteThread(MyBuffer obj,RandomAccessFile writeFile,String threadName) {
              // TODO Auto-generated constructor stub
              this.t = new Thread(this,threadName);
              this.file = writeFile;
              this.buffer = obj;
              this.t.start();
          }
      
          WriteThread(MyBuffer obj,FileOutputStream writeFos,String threadName) {
              // TODO Auto-generated constructor stub
              this.t = new Thread(this,threadName);
              this.fos = writeFos;
              this.buffer = obj;
              this.t.start();
          }
          @Override
          public void run() {
              // TODO Auto-generated method stub
              try {
                  while(true){
                          if(this.buffer.getBytes()!=null){
                              MyBuffer.isWriting = true;
                              if(this.file!=null){
                                  this.file.write(this.buffer.getBytes());
                              }else if(this.fos!=null){
                                  this.fos.write(this.buffer.getBytes());
                              }
                              this.buffer.clearBytes();
                          }else{
                              if(MyBuffer.readComplete)
                                  break;
      
                              MyBuffer.isWriting = false;
                          }
                  }
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      }
      public class ReadWriteModifyMain {
          public static void main(String[] args) {
              new MyBuffer(new File("C:\\Users\\Manoj\\Samples\\Samplers\\src.txt"),new File("C:\\Users\\Manoj\\Samples\\Samplers\\des.txt"));
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-11-20
        • 1970-01-01
        • 2011-06-09
        • 2023-04-01
        • 2018-07-06
        • 1970-01-01
        • 2015-07-03
        相关资源
        最近更新 更多