Печать с "\t" (вкладки) не приводит к выравниванию столбцов
У меня очень странная проблема. После написания этого:
for (File f : currentFile.listFiles()) {
if (f.isDirectory()){
System.out.println(f.getName()+"\t"+"Dir\t"+Command.getpremission(f)+"\t"+f.getTotalSpace());
}
else{
System.out.println(f.getName()+"\t"+"File\t"+Command.getpremission(f)+"\t"+f.getTotalSpace());
}
Я вижу это напечатано:
see.txt File rw 267642728448
see1.txt File rw 267642728456
see2.txt File rw 267642728448
Почему проблема с вкладками?
8 ответов
Основываясь на этом вопросе, я использую следующий код для отступа моих сообщений:
String prefix1 = "short text:";
String prefix2 = "looooooooooooooong text:";
String msg = "indented";
/*
* The second string begins after 40 characters. The dash means that the
* first string is left-justified.
*/
String format = "%-40s%s%n";
System.out.printf(format, prefix1, msg);
System.out.printf(format, prefix2, msg);
Это вывод:
краткий текст: отступ Текст "оооооооооооо": отступ
"Проблема" с вкладками заключается в том, что они имеют отступ текста от фиксированных позиций вкладок, обычно кратных 4 или 8 символам (в зависимости от того, какая консоль или редактор их отображают). Ваше первое имя файла имеет 7 символов, поэтому следующая позиция табуляции после его конца находится в позиции 8. Однако последующие имена файлов имеют длину 8 символов, поэтому следующая позиция табуляции находится в позиции 12.
Если вы хотите, чтобы столбцы были правильно смещены в одну и ту же позицию, вам необходимо принять во внимание фактическую длину предыдущих столбцов и либо изменить количество следующих вкладок, либо вместо этого заполнить нужным количеством пробелов. Последнее может быть достигнуто с помощью, например, System.out.printf
с соответствующей спецификацией формата (например, "%1$13s"
задает минимальную ширину 13 символов для отображения первого аргумента в виде строки).
Длина текста, который вы предоставляете в каждой строке, отличается, это проблема, поэтому, если второе слово слишком длинное (see2.txt
длиной 8 символов, что соответствует длине одной вкладки), она распечатывает вкладку, которая переходит к следующей точке табуляции. Один из способов решить эту проблему - программно добавить пэд к f.getName()
текст так каждый текст генерируется: see.txt
или же see2.txt
имеет одинаковую длину (например, see.txt_
а также see2.txt
) поэтому каждая вкладка автоматически переходит к одной и той же точке табуляции.
Если вы разрабатываете с JDK 1.5, вы можете решить эту проблему с помощью java.util.Formatter:
String format = "%-20s %5d\n";
System.out.format(format, "test", 1);
System.out.format(format, "test2", 20);
System.out.format(format, "test3", 5000);
этот пример даст вам этот отпечаток:
test 1
test2 20
test3 5000
В продолжение комментариев Петера и Дункана я обычно использую метод быстрого заполнения, что-то вроде -
public String rpad(String inStr, int finalLength)
{
return (inStr + " " // typically a sufficient length spaces string.
).substring(0, finalLength);
}
Точно так же вы можете иметь lpad()
также
Как упоминали другие люди, проблема заключается в переменной длине строки.
Вместо того, чтобы изобретать велосипед, у Apache Commons есть хорошее, чистое решение для этого в StringUtils.
StringUtils.rightPad("String to extend",100); //100 is the length you want to pad out to.
Проблема в длине имен файлов. Первое имя файла имеет длину всего 7 символов, поэтому вкладка отображается на 8-ом символе (после каждого 4 символа выполняется вкладка). Однако следующие имена файлов имеют длину 8 символов, поэтому следующая вкладка будет отображаться только до 12 символа. И если у вас имена файлов длиннее 11 символов, вы снова столкнетесь с той же проблемой.
Вы можете использовать этот пример для решения вашей проблемы:
System.out.printf( "%-15s %15s %n", "name", "lastname");
System.out.printf( "%-15s %15s %n", "Bill", "Smith");
Вы можете играть с "%", пока не найдете правильное выравнивание, чтобы удовлетворить ваши потребности
Вы также можете дополнить строку до необходимой длины, используя Guava's Strings.padEnd (String input, int minLength, padding)