Почему я не могу читать из / proc в Java, используя Commons IO FileUtils, но могу сделать это с помощью простого FileInputStream? - PullRequest
1 голос
/ 16 августа 2011

У меня была проблема с чтением /proc/%d/stat файлов с использованием моего метода Java copyFiles () (исходный код ниже). Я нашел обходной путь, используя аналогичный метод readProc ().

Теперь мне интересно, в чем была проблема. Выходные файлы были созданы, но каждый файл имел 0 байтов (в / proc / все файлы - 0 байтов, потому что это не стандартная файловая система). FileUtils из библиотеки ввода-вывода Apache Commons.

Я пытался сделать то же самое, используя java.nio - опять выдается IOException, что атрибуты неверны для каждого файла.

Я удалил некоторую часть кода, касающуюся анализа исключений и т. Д.

Почему это работает с FileInputStream, но не с FileUtils.copyFile()?

public void copyFiles() {
    final File dir = new File("/proc");
    final String[] filedirArray = dir.list();
    long counter = 0;
    for(String filedir : filedirArray) {
            final File checkFile = new File(dir, filedir);
            if (checkFile.isDirectory()) {
                    try {
                            Integer.parseInt(filedir);
                            File srcFile = new File(checkFile, "stat");
                            File dstFile = new File("/home/waldekm/files/stat" + "." + Long.toString(counter++));
                            try {                                    
                                FileUtils.copyFile(srcFile, dstFile);
                            } catch (IOException e1) {}
                    } catch (NumberFormatException e) {
                            // not a number, do nothing
                    }                        
            }
    }
}

public static void readProc(final String src, final String dst) {
    FileInputStream in = null;
    FileOutputStream out = null;

    File srcFile = new File(src);
    File dstFile = new File(dst);

    try {
        in = new FileInputStream(srcFile);
        out = new FileOutputStream(dstFile);
        int c;
        while((c = in.read()) != -1) {
            out.write(c);
        }
    } catch (IOException e1) {
 }  finally {

        try {
            if (in != null) {
                in.close();
            }
        } catch (IOException e1) {}
        try {
            if (out != null) {
                out.close();
            }
        } catch (IOException e1) {}
    }

Ответы [ 3 ]

2 голосов
/ 16 августа 2011

Причина, скорее всего, в том, что операционная система сообщает, что размер файла равен нулю.

На моей машине man 2 stat говорит следующее:

" Для большинства файлов в каталоге /proc, stat() не возвращает размер файла в поле st_size; вместо этого возвращается поле со значением 0. "

(Системный вызов stat будет использоваться JVM для определения размера файла.)

1 голос
/ 23 июня 2013

Вот фрагмент кода, который считывает определенные поля из файла proc, используя методы, которые доступны (но не документированы напрямую) в классе Process Android.Измените буфер FORMAT и размер выходного буфера, чтобы считывать больше / другие значения из файла proc,

int PROC_SPACE_TERM = (int)' ';
int PROC_OUT_LONG = 0x2000

public static final int[] PROCESS_STATS_FORMAT = new int[] {
    PROC_SPACE_TERM,
    PROC_SPACE_TERM,
    PROC_SPACE_TERM,
    PROC_SPACE_TERM,
    PROC_SPACE_TERM,
    PROC_SPACE_TERM,
    PROC_SPACE_TERM,
    PROC_SPACE_TERM,
    PROC_SPACE_TERM,
    PROC_SPACE_TERM,
    PROC_SPACE_TERM,
    PROC_SPACE_TERM,
    PROC_SPACE_TERM,
    PROC_SPACE_TERM|PROC_OUT_LONG,                  // 13: utime
    PROC_SPACE_TERM|PROC_OUT_LONG                   // 14: stime
};

long buf[] = new long[2];

try {
    int pid = 1000; // Assume 1000 is a valid pid for a process. 
    Method mReadProcFile = 
              Process.class.getMethod("readProcFile", String.class,
                                      int[].class, String[].class,   
                                      long[].class, float[].class);
    mReadProcFile.invoke(null, "/proc/" + pid + "/stat", 
                         PROCESS_STATS_FORMAT, null, buf, null);

    return buf;

} catch(NoSuchMethodException e) {
    Log.e(TAG, "Error! Could not get access to JNI method - readProcFile");
} catch (InvocationTargetException e) {
Log.e(TAG, "Error! Could not invoke JNI method - readProcFile");
} catch (IllegalAccessException e) {
    Log.e(TAG, "Error! Illegal access while invoking JNI method - readProcFile");
}

return null;
0 голосов
/ 15 января 2017

Я вижу, вы создаете FileInputStream для чтения файла / proc.Вместо этого я предлагаю вам создать объект FileReader.FileInputStream отключается из-за отсутствия длины файла для файлов / proc, а FileReader - нет.

...