Как я заставляю команду находки распечатывать размер файла с именем файла?

Что такое NullPointerException?

Хорошим местом для начала является JavaDocs . Они охватывают это:

Брошено, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  • Вызов метода экземпляра нулевого объекта.
  • Доступ или изменение поля нулевого объекта.
  • Выполнение длины null, как если бы это был массив.
  • Доступ или изменение слотов с нулевым значением, как если бы это был массив.
  • Бросать нуль, как если бы это было значение Throwable.

Приложения должны бросать экземпляры этого класса для указания других незаконных видов использования нулевого объекта.

Также, если вы попытаетесь использовать нулевую ссылку с synchronized, который также выдаст это исключение, за JLS :

SynchronizedStatement:
    synchronized ( Expression ) Block
  • В противном случае, если значение выражения равно null, NullPointerException.

Как это исправить?

Итак, у вас есть NullPointerException. Как вы это исправите? Возьмем простой пример, который выдает NullPointerException:

public class Printer {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public void print() {
        printString(name);
    }

    private void printString(String s) {
        System.out.println(s + " (" + s.length() + ")");
    }

    public static void main(String[] args) {
        Printer printer = new Printer();
        printer.print();
    }
}

Идентифицирует нулевые значения

. Первый шаг - точно определить , значения которого вызывают исключение . Для этого нам нужно выполнить некоторую отладку. Важно научиться читать stacktrace . Это покажет вам, где было выбрано исключение:

Exception in thread "main" java.lang.NullPointerException
    at Printer.printString(Printer.java:13)
    at Printer.print(Printer.java:9)
    at Printer.main(Printer.java:19)

Здесь мы видим, что исключение выбрано в строке 13 (в методе printString). Посмотрите на строку и проверьте, какие значения равны нулю, добавив протоколирующие операторы или используя отладчик . Мы обнаруживаем, что s имеет значение null, а вызов метода length на него вызывает исключение. Мы видим, что программа прекращает бросать исключение, когда s.length() удаляется из метода.

Трассировка, где эти значения взяты из

Затем проверьте, откуда это значение. Следуя вызовам метода, мы видим, что s передается с printString(name) в методе print(), а this.name - null.

Трассировка, где эти значения должны быть установлены

Где установлен this.name? В методе setName(String). С некоторой дополнительной отладкой мы видим, что этот метод вообще не вызывается. Если этот метод был вызван, обязательно проверьте порядок , что эти методы вызывают, а метод set не будет называться после методом печати. ​​

Этого достаточно, чтобы дать нам решение: добавить вызов printer.setName() перед вызовом printer.print().

Другие исправления

Переменная может иметь значение по умолчанию setName может помешать ему установить значение null):

private String name = "";

Либо метод print, либо printString может проверить значение null например:

printString((name == null) ? "" : name);

Или вы можете создать класс, чтобы name всегда имел ненулевое значение :

public class Printer {
    private final String name;

    public Printer(String name) {
        this.name = Objects.requireNonNull(name);
    }

    public void print() {
        printString(name);
    }

    private void printString(String s) {
        System.out.println(s + " (" + s.length() + ")");
    }

    public static void main(String[] args) {
        Printer printer = new Printer("123");
        printer.print();
    }
}

См. также:

Я все еще не могу найти проблему

Если вы попытались отладить проблему и до сих пор не имеете решения, вы можете отправить вопрос для получения дополнительной справки, но не забудьте включить то, что вы пробовали до сих пор. Как минимум, включите stacktrace в вопрос и отметьте важные номера строк в коде. Также попробуйте сначала упростить код (см. SSCCE ).

89
задан 4 revs, 2 users 91% 6 December 2015 в 18:32
поделиться

9 ответов

find . -name '*.ear' -exec ls -lh {} \;

просто h дополнительное от ответа jer.drab.org. экономит время, преобразовывая в МБ мысленно;)

95
ответ дан shyam 24 November 2019 в 07:11
поделиться
find . -name "*.ear" -exec ls -l {} \;
0
ответ дан Benjamin 24 November 2019 в 07:11
поделиться
find . -name "*.ear" | xargs ls -sh
1
ответ дан Igor 24 November 2019 в 07:11
поделиться

Вы могли попробовать это:

find. -name *.ear -exec du {} \;

Это даст Вам размер в байтах. Но команда du также принимает параметры-k для КБ и-m для МБ. Это даст Вам вывод как

5000  ./dir1/dir2/earFile1.ear
5400  ./dir1/dir2/earFile2.ear
5400  ./dir1/dir3/earFile1.ear
1
ответ дан Yaba 24 November 2019 в 07:11
поделиться

Используя гну находят, я думаю, что это - то, что Вы хотите. Это находит, что все реальные файлы и не каталоги (-тип f), и для каждого печатают имя файла (%p), вкладка (\t), размер в килобайтах (К), суффиксном "КБ", и затем новой строке (\n).

find . -type f -printf '%p\t%k KB\n'

, Если команда printf не форматирует вещи путем, Вы хотите, можно использовать должностное лицо, сопровождаемое командой, которую Вы хотите выполнить на каждом файле. Используйте {} для имени файла и завершите команду с точкой с запятой (;). На большинстве оболочек всех трех из тех символов нужно оставить с обратной косой чертой.

Вот простое решение, которое находит и печатает их использующий "ls - люфтганза", которая покажет Вам размер в человекочитаемой форме (k для килобайтов, M для мегабайтов):

find . -type f -exec ls -lh \{\} \;

Пока еще другая альтернатива, "туалет-c" распечатает количество символов (байты) в файле:

find . -type f -exec wc -c \{\} \;
20
ответ дан kenorb 24 November 2019 в 07:11
поделиться

Awk может согласовать вывод для предоставления, что попросил корреспондент. На моем Солярисе 10 систем найдите, что-ls печатает размер в КБ как второе поле, таким образом:

% find . -name '*.ear' -ls | awk '{print $2, $11}'
5400 ./dir1/dir2/earFile2.ear
5400 ./dir1/dir2/earFile3.ear
5400 ./dir1/dir2/earFile1.ear

Иначе, используйте - должностное лицо ls - люфтганза и выберите поле размера от вывода. Снова на Солярисе 10:

% find . -name '*.ear' -exec ls -lh {} \; | awk '{print $5, $9}'
5.3M ./dir1/dir2/earFile2.ear
5.3M ./dir1/dir2/earFile3.ear
5.3M ./dir1/dir2/earFile1.ear
4
ответ дан tpgould 24 November 2019 в 07:11
поделиться

Необходимо использовать - должностное лицо или-printf. Printf работает как это:

find . -name *.ear -printf "%p %k KB\n"

- должностное лицо более мощно и позволяет Вам выполнить произвольные команды - таким образом, Вы могли использовать версию 'ls' или 'туалета' для распечатывания имени файла наряду с другой информацией. 'человек находит', покажет Вам доступные аргументы printf, который может сделать намного больше, чем просто размер файла.

[редактирование]-printf не находится в официальном стандарте POSIX, таким образом проверьте, поддерживается ли это на Вашей версии. Однако большинство современных систем будет использовать GNU, находят или столь же расширенная версия, таким образом, существует хороший шанс, это будет реализовано.

96
ответ дан Leigh Caldwell 24 November 2019 в 07:11
поделиться

простое решение должно использовать-ls опцию в находке:

find . -name \*.ear -ls

, Который дает Вам каждую запись в нормальном "ls-l" формат. Или, для получения определенного вывода Вы, кажется, ищете, это:

find . -name \*.ear -printf "%p\t%k KB\n"

, Который даст Вам имя файла, сопровождаемое размером в КБ.

21
ответ дан Michael Cramer 24 November 2019 в 07:11
поделиться
[
$ find . -name "test*" -exec du -sh {} \;
4.0K    ./test1
0       ./test2
0       ./test3
0       ./test4
$
] [

][]Мировая ссылка на скриптер[][

]
1
ответ дан 24 November 2019 в 07:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: