问题描述:本人在读一个很大的文件,大概100M,因为用BufferedReader读取速度太慢,所以想用多线程读取,现在已经可以把文件内容打印到控制台输入,但是在run方法中往SWT的StyledText中添加时从是报空指针异常,如:org.eclipse.swt.SWTException: Invalid thread access
at org.eclipse.swt.SWT.error(SWT.java:3563)
at org.eclipse.swt.SWT.error(SWT.java:3481)
at org.eclipse.swt.SWT.error(SWT.java:3452)
at org.eclipse.swt.widgets.Widget.error(Widget.java:432)
at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:326)
at org.eclipse.swt.custom.StyledText.append(StyledText.java:1476)
at shiyan.FileDrag$FileThread.run(FileDrag.java:582)
at java.lang.Thread.run(Unknown Source)下面把线程代码贴出来,请各位大侠帮忙看下什么问题,应该怎么解决,小弟非常感谢
//线程类
 public class FileThread implements Runnable  {         // 分块总数
        private int blockCount;
        // 开始读取的块序号
        private int blockNo;
        // 缓存大小
        private int maxBuffSize = 1024 * 1024;
        // 来源文件
        private String sourceFile;
        // 目标文件
        private String targetFile;
        public StyledText stytext;
        String result="";

        /**
         * 将sourceFile文件分blockCount块后的第blockNo块复制至sourceFile
         * 
         * @param sourceFile 来源文件全名
         * @param targetFile 目标文件全名
         * @param blockCount 文件分块读取数
         * @param blockNo 开始读取的块序号
         */
        public FileThread(String sourceFile, String targetFile, int blockCount,int blockNo,StyledText styledTextUI) {
            this.sourceFile = sourceFile;
            this.targetFile = targetFile;
            this.blockCount = blockCount;
            this.blockNo = blockNo;
            this.stytext = styledTextUI;
          
            
            
        }
        public void run() {             // 得到来源文件
            File file = new File(sourceFile);
            // 得到来源文件的大小
            long size = file.length();
            // 根据文件大小及分块总数算出单个块的大小
            long blockLenth = size / blockCount;
            // 算出当前开始读取的位置
            long startPosition = blockLenth * blockNo;
            // 实例化缓存
            byte[] buff = new byte[maxBuffSize];
            InputStream is = null;
            RandomAccessFile raf = null;
            try {
                // 从源文件得到输入流
                is = new FileInputStream(sourceFile);
                // 得到目标文件的随机访问对象
              //  raf = new RandomAccessFile(targetFile, "rw");
                // 将目标文件的指针偏移至开始位置
             //   raf.seek(startPosition);
                // 当前读取的字节数
                int curReadLength = 0;
                // 累计读取字节数的和
                int totalReadLength = 0;
                // 将来源文件的指针偏移至开始位置
                is.skip(startPosition);
//                 stytext.append("添加上了么");
                // 依次分块读取文件
                while ((curReadLength = is.read(buff)) > 0
                    && totalReadLength < blockLenth) {
                    // 将缓存中的字节显示
                  //  raf.write(buff, 0, curReadLength);
                 result =new String(buff,0,curReadLength);
                 System.out.println(result);
                 stytext.append(result);
                 //System.out.println();
                    // 累计读取的字节数
                    totalReadLength += curReadLength;
                }
            }
            catch (Exception ex) {
                ex.printStackTrace();
            }
            finally {
                // 关闭相关资源
                try {
                    if (raf != null) {
                        raf.close();
                    }
                    if (is != null) {
                        is.close();
                    }
                }
                catch (IOException ex) {
                    ex.printStackTrace();
                    raf = null;
                    is = null;
                }             }
           
        }     }//以下是调用线程的两个方法
  public void readerFilesThread(String sourceFile, String targetFile, int blockCount,StyledText styledText ) {        // 依次分块进行文件COPY
        for (int i = 0; i < blockCount; i++) {
            // 实例化文件复制对象
            FileThread fileThread = new FileThread(sourceFile, targetFile, blockCount, i,styledText);
            // 实例化线程
            Thread thread = new Thread(fileThread);
            // 开始线程
            thread.start();
            try {
                // 加入线程
                thread.join();
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
public void ReaderFile(){
// String str = "";
if (!text.getText().trim().equals("")) {
text.setText("");
}
String name = file.substring(file.lastIndexOf("\\") + 1, file.length());
item1.setText(name);

if (!file.equals(" ")) {

        String sourceFile = file;
        String targetFile = "";
        int blockCount = 5;
        long beginTime = System.currentTimeMillis();
        this.readerFilesThread(sourceFile, targetFile, blockCount,text);
        long endTime = System.currentTimeMillis();
        System.out.println("共用时:" + (endTime - beginTime) + "ms");
        //坚定拖动事件
        this.Actions();
}
}请各位大侠帮忙看下,谢谢了

解决方案 »

  1.   

    org.eclipse.swt.SWTException: Invalid thread access 
    这个不是空指针,是线程访问错误,SWT不允许非UI线程直接访问UI线程。在非UI线程里,要用这种形式访问UI:display.syncExec(
      new Runnable() {
        public void run(){
          label.setText(text);
        }
      });参考:
    http://www.eclipse.org/swt/faq.php
      

  2.   

    多谢大侠,我还有个问题想请教一下,就是我在程序中写了个带关闭按钮的CTabItem,在CTabItem中有个StyledText,文件读出来的内容显示到了STyledText中。内存由原来的17M增加到了190M,当我关闭CTabItem时,内存没有下降,如果在执行一次内存只是在曾加而没有下降,请问大侠知道什么原因么?