Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在文件读/写时使用线程?_Java_Multithreading_Ioexception - Fatal编程技术网

Java 如何在文件读/写时使用线程?

Java 如何在文件读/写时使用线程?,java,multithreading,ioexception,Java,Multithreading,Ioexception,家庭作业要求我实现一个程序,通过为每个文件启动一个新线程来计算一个或多个文件(文件名在命令行上指定为参数)中的单词数 我的问题是:run()方法不能抛出IOException,因为Runnable接口中的run()方法不会抛出IOException。我把文件和扫描器构造函数调用放在实现Runnable的类的构造函数中,绕过了编译器的警告,但即使它现在编译得很好,我还是觉得有些可疑,好像我在做一些不符合犹太教义的事情。有什么想法吗 import java.io.File; import java.

家庭作业要求我实现一个程序,通过为每个文件启动一个新线程来计算一个或多个文件(文件名在命令行上指定为参数)中的单词数

我的问题是:run()方法不能抛出IOException,因为Runnable接口中的run()方法不会抛出IOException。我把文件和扫描器构造函数调用放在实现Runnable的类的构造函数中,绕过了编译器的警告,但即使它现在编译得很好,我还是觉得有些可疑,好像我在做一些不符合犹太教义的事情。有什么想法吗

import java.io.File;
import java.util.Scanner;
import java.io.FileNotFoundException;
import java.io.IOException;

public class WordCounter implements Runnable {
    File inFile;
    Scanner in;
    int characters;
    int words;
    int lines;
    int[] counted;

    public WordCounter(String aFile) throws FileNotFoundException {
        inFile = new File(aFile);
        in = new Scanner(inFile);
        counted = new int[3];
    }

    public int[] getTotals() {
        return counted;
    }

    public void run() {
        characters = 0;
        words = 0;
        lines = 0;
        while (in.hasNextLine()) {

            String thisLine = in.nextLine();
            lines++;
            Scanner line = new Scanner(thisLine);
            while (line.hasNext()) {
                String thisWord = line.next();
                words++;
                characters++; // because each call to line.next() strips a whitespace character
                Scanner word = new Scanner(thisWord);
                word.useDelimiter("");
                while (word.hasNext()) {
                    char ch = word.next().charAt(0);
                    characters++;
                }
            }
        }
        counted[0] = characters;
        counted[1] = words;
        counted[2] = lines;
    }

}

在构造函数中初始化成员变量通常是一种好的做法。我认为您做的是正确的,而且,我会将
字符
单词
、和
的初始化也移到构造函数中。

您可以使异常静音,并中止线程内的文件操作。关闭异常是否是一个好主意取决于您试图做什么

try {
    inFile = new File(aFile);
} catch (FileNotFoundException e) {
    System.out.println("file not found, aborting operation.");
    return;
}

但是,我认为在构造函数中初始化文件没有什么错;如果您希望尽早失败,而不是等到以后再失败,这是一个非常好的做法。

如果问题是已检查的异常,那么一个常见的习惯用法是将其转换为RuntimeException,如下所示:

try {
 ...
} catch (IOException e) {
    throw new RuntimeException(e);
}

基本上,你抓,转化和再抓。RuntimeException被取消选中,因此方法签名不需要声明它。

我认为一般的经验法则是尽可能靠近抛出异常的位置来处理异常。是什么阻止您的runnable处理异常而不是main()或创建runnable的任何东西


我同意变量初始化通常最好在构造函数中完成,但是当使用runnables时,如果在run()方法中进行构造,您将获得更好的性能。我特别谈论的变量实际上需要一些时间来处理;int[3]不会对构造函数或run方法产生影响,但扫描程序和文件可能取决于它们在初始化时所做的操作(例如,扫描程序是否缓冲文件的第一行?)。

在我看来,这是个坏主意。您现在有一个未经检查的异常,编译器不会警告您。这样做有什么意义?异常仍然会被抛出,但现在要到运行时才会被捕获。我曾想过这样做,但在本章之前的章节中,鼓励学生不要在课堂上捕获异常,因为在课堂上,您可能无法像您(或其他程序员)那样有效地处理异常可以在使用类的主方法中处理它们。(希望这是有意义的…)我想我还是有点不确定什么时候该做出判断。说到底,这是一个判断。这只是我的意见。如果您的runnable无法处理扫描程序/文件引发的异常,那么为什么让您的runnable实例化这些类型?为什么不将有效的扫描程序传递到Runnable中呢。这将使您的try/catch位于main()中,听起来似乎就是您要处理此异常的地方。除了例外,你最终做的事情才是最重要的。如果你能从中恢复过来,那就扔掉它。如果您只是想记录日志并默默地失败,我建议您在Runnable中捕获它。