2011-01-22 2 views
0

Я учусь читать и писать на Java и застрял в простом упражнении. Программа читает из 2 txt-файлов, каждая из которых содержит числа в строках. Он записывает в выходной файл результат умножения каждой строки чисел. например. файл 1 строка 1: 10, файл 2 строка 1: 2, программа должна записать 20 в выходной файл. У моего кода, похоже, что-то отсутствует. Выходной файл создается, но на него ничего не записывается. Есть идеи?DataInputStream для ввода текстовых файлов?

import java.io.*; 
import java.util.*; 

class ReadWriteData 
{ 
    public static void main(String[] args) throws Exception 
    { 

     //create ouput file 
     PrintWriter output = new PrintWriter("output2.txt"); 

     DataInputStream file1 = new DataInputStream(new FileInputStream(args[0])); 
     DataInputStream file2 = new DataInputStream(new FileInputStream(args[1])); 

     try 
     { 

     // read data from file 
     while (true) 
     { 
      double number1 = file1.readDouble(); 
      double number2 = file2.readDouble(); 
      double result = number1 * number2 ; 
      output.println(result); 

     } 


     } 

     catch (IOException e) 
     { 
      System.err.println("Error"); 
      System.exit(1); 
     } 

     output.close() ; 

    } 
} 

ответ

4

Вот реализация с BufferedReader, которая работает.

public static void main(String[] args) throws Exception { 
    //create ouput file 
    PrintWriter output = new PrintWriter("output2.txt"); 
    BufferedReader file1 = new BufferedReader(new FileReader("numbers1.txt")); 
    BufferedReader file2 = new BufferedReader(new FileReader("numbers2.txt")); 

    try { 
     // read data from file 
     while (true) { 
      String number1AsString = file1.readLine(); 
      String number2AsString = file2.readLine(); 
      if (number1AsString == null || number2AsString == null) { 
       break; 
      } 
      double number1 = Double.parseDouble(number1AsString); 
      double number2 = Double.parseDouble(number2AsString); 
      double result = number1 * number2; 
      System.out.println("result:" + result); 
      output.println(result); 
     } 
    } catch (IOException e) { 
     System.out.println(e.getMessage()); 
    } finally { 
     output.close(); 
     file1.close(); 
     file2.close(); 
    } 
} 

Edit: Кроме того, вы можете модуляризуете код, например, создать метод, который поможет уменьшить дублирование кода. Также вам может быть интересно найти NumberFormatException в случае, если какое-либо число не отформатировано должным образом или, например, содержит буквы.

private double readDoubleFromFile(BufferedReader file) throws IOException { 
    String numberAsString = file.readLine(); 
    if (numberAsString == null) { 
     throw new IOException(); 
    } 
    double number = Double.parseDouble(numberAsString); 
    return number; 
} 
0

Вам необходимо вывести вывод. flush перед закрытием потока. Кроме того, вы должны закрыть потоки в файлах в блоке finally, это будет гарантировать, что команда закрытия всегда будет выполняться.

4

Класс DataInputStream не предназначен для чтения текстовых файлов. его можно использовать только для чтения того, что пишет DataOutput. Если у вас есть строки чисел человека считываемых, вы должны использовать InputStreamReader и затем проанализировать полученные потоки с вещами как Double.parseDouble

+0

Очень верно, но будет ли конкретный фрагмент когда-либо выполняться успешно и создать пустой файл без каких-либо исключений? – BalusC

+0

Я думаю, что фрагмент был «не исключительным» из-за неспособности закрыть выход, как указано в других ответах. – bmargulies

0

После

output.println(result); 

добавить

output.flush(); 
+2

Если исключение не было выбрано, закрыть уже неявно называется flush. – BalusC

+0

Я только что протестировал его, вы правы. благодаря – metter

1

DataInputStream класса читает от файла двоичного файла (или другого источника, такого как сокет). Это означает, что он будет полностью неверно истолковывать эти входные текстовые файлы, возможно, с забавными (или очень раздражающими) результатами. Чтобы читать числа из текстового файла, вы должны использовать BufferedReader, обертывая InputStreamReader, чтобы читать строки, а затем преобразовывать их в числа с подходящими методами парсинга (например, Double.parseDouble, если вы хотите создать число с плавающей запятой).

При тестировании этих вещей часто полезно добавить в цикл какой-то отладочный вывод, который печатает каждое значение при его чтении. Таким образом, вы можете увидеть, если что-то застряло неожиданным образом.

2

Возможно, вы хотите использовать BufferedReader для этого.

BufferedReader in = new BufferedReader(
          new FileReader(args[0])); 

Тогда:

String num = null; 
    while((num = in.readLine()) != null){ 
     double d = Double.parseDouble(num); 
     //now you have a double value 
    } 

Таким образом, вы не зависят от исключения, чтобы указать конец файла.

1

С этим while (true) без break ваш код в основном работает в бесконечном цикле и никогда не останавливается, если не существует исключения.

Если оно завершено, но вы не видели исключения, это может быть вызвано вызовом System.exit(1) в catch. Может быть, слишком поздно, чтобы печатать "Error" в любом случае (stdout, возможно, был прерван слишком рано), и файл никогда не будет краснет/закрыт. Удалите эту линию System.exit(1).

Также предполагается, что закрытие должно состоять из finally блока. Лучше всего не печатать какое-то сообщение-сообщение об исключении, а просто отпустить их. Поскольку у вас уже есть метод throws Exception, просто удалите весь catch. Используйте его только тогда, когда вы можете обрабатывать исключения в методе разумным способом.

PrintWriter output = new PrintWriter("output2.txt"); 
try { 
    output.println("something"); 
} finally { 
    output.close(); 
} 
Смежные вопросы