Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > как отличить XML от Excel?


Автор: #Maestro# 20.4.2009, 09:36
 очень надо программно открыть Excel и XML-файл и показать его пользователю. вот как выглядит моя функция:

Код

JFileChooser chooser = new JFileChooser();
    FileNameExtensionFilter filter = new FileNameExtensionFilter(
        "Excel files", "xls");
    chooser.setFileFilter(filter);

     FileNameExtensionFilter filter1 = new FileNameExtensionFilter(
        "XML files",  "xml");
       chooser.setFileFilter(filter1);
    int returnVal = chooser.showOpenDialog(this);
    if(returnVal == JFileChooser.APPROVE_OPTION) {
       System.out.println("You chose to open this file: " +
            chooser.getSelectedFile().getName());
       //File f=chooser.getSelectedFile();

       
      
    int returnVal1 = chooser.showOpenDialog(this);
    if(returnVal1 == JFileChooser.APPROVE_OPTION) {
       System.out.println("You chose to open this file: " +
            chooser.getSelectedFile().getName());
       File f=chooser.getSelectedFile();


дальше следует выбрать функцию обработки файла (Excel или XML фалов, в зависимости от выбора). вопрос:
 как узнать тип этого выбранного файла? то есть: какую функцию мне вызвать - обработки Excel-файла? или XML?

Автор: yuliada 20.4.2009, 09:41
По идее xml должен всегда начинаться с тега xml, можно почитать в файлике первую строчку

Автор: Amp 20.4.2009, 09:49
xls-файл начинает с 8-и байтовой сигнатуры специфичной для compound documents - D0 CF 11 E0 A1 B1 1A E1

Автор: #Maestro# 20.4.2009, 15:29
Поставим вопрос по-другому.  переменная fName (типа String) содержит имя полное файла. может быть существует функция, способная определить расширение?
я решил вопрос по-рабоче-крестьянски:
Код

File f=chooser.getSelectedFile();
       String fName = f.getName();
       String fEnd = fName.substring(fName.indexOf(".")+1);
     if(fEnd.equals("xml"))
     {
  xmlProcess(f);
     }

может кто скажет вариант по-проще?

Автор: goodday1941 20.4.2009, 20:49
можно и так конечно, но можно и так:
Код

yourString.toLowerCase().endsWith().equals(".xml")


Добавлено через 1 минуту и 4 секунды
а вообще все типы файлов которые ты можешь читать я бы вынес в enum

Автор: #Maestro# 21.4.2009, 09:10
если б мне знать что такое enum...

вы это имеете ввиду:

Код
 public enum FileFormat {xls, xml}; 

??
а как потом это работает?

Автор: _and 21.4.2009, 10:06
это енум
Код

public enum FileTypes {
    XML("xml"),
    XSL("xsl");
    private String fileType;

    FileTypes(String s) {
        this.fileType = s;
    }

    public String getFileType() {
        return fileType;
    }

    public void setFileType(String fileType) {
        this.fileType = fileType;
    }

}

а так его пользовать
Код

FileTypes ft =  FileTypes.valueOf("XML");
        switch (ft) {
            case XML:
                System.out.println("XML");
                break;
            case XSL:
                System.out.println("XSL");
                break;
        }

Автор: #Maestro# 21.4.2009, 11:05
 уважаемый _and, мне не совсем понятно чем отличаются функции FileTypes и setFileType. по-моему их логика совершенно одинакова. и ещё:
если не трудно, не могли бы вы пояснить работу FileTypes.valueOf("XML")?
заранее спосибо!

Автор: _and 21.4.2009, 11:32
Цитата(#Maestro# @  21.4.2009,  15:05 Найти цитируемый пост)
чем отличаются функции FileTypes и setFileType

FileTypes - конструктор
IDEA у меня автоматом генерит getter и  setter методы, можно и без него обойтись
посомтри http://www.javenue.info/post/73 - кратко по enum и http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html официальая дока
Цитата(#Maestro# @  21.4.2009,  15:05 Найти цитируемый пост)
если не трудно, не могли бы вы пояснить работу FileTypes.valueOf("XML")?

из jacadoc
Код

Returns the enum constant of the specified enum type with the
specified name.  The name must match exactly an identifier used
to declare an enum constant in this type.  (Extraneous whitespace
characters are not permitted.)

класс FileTypes есть enum, и является подклассом java.lang.Enum соответственно наследует метод valueOf(...)

Автор: math64 21.4.2009, 12:05
В нормальном enum setFileType() не должно быть, иначе можно сделать:
Код

FileTypes.XML.setFileType("xsl");

и у обоих членов enum будет одно и то же значение поля fileType.

Автор: #Maestro# 21.4.2009, 13:36
честно говоря, я тоже не совсем понял зачем создавать такой конструктор, если есть функция set()

Автор: LSD 21.4.2009, 14:23
А нафига нужно поле fileType smile 


Не говоря уж о том, что под Windows файл может иметь расширение и xml,  и XML, и XmL и это будет одно и то же расширение.

Добавлено через 1 минуту и 50 секунд
Вообщем вариант
Цитата(#Maestro# @  20.4.2009,  15:29 Найти цитируемый пост)
я решил вопрос по-рабоче-крестьянски:
...

самый нормальный, если в нем учесть регистр. А вообще у Апача есть куча утилит для работы с файлами которые все это учитывают.

Автор: Asal 21.4.2009, 15:42
Цитата(LSD @  21.4.2009,  14:23 Найти цитируемый пост)
Не говоря уж о том, что под Windows файл может иметь расширение и xml,  и XML, и XmL и это будет одно и то же расширение.


Цитата(LSD @  21.4.2009,  14:23 Найти цитируемый пост)
самый нормальный, если в нем учесть регистр. 

А почему никто не прислушался к Amp, человек же дело сказал!
Расширение же у файла может быть любое, и в винде, и под линем.
Код

import java.io.*;
import java.util.Arrays;

/**
 * @author Alexander Salnikov
 * @version 0.1
 */
public class Main {


    public static void main(String... args) throws IOException {
        File f = new File("C:\\test.xls");
        HexCodec codec = new HexCodec();
        if (f.exists() && f.isFile()) {
            FileInputStream is = new FileInputStream(f);

            byte[] bArray = new byte[8];
            is.read(bArray, 0, 8);
            is.close();
            if (Arrays.equals(codec.bytesToHex(bArray), ("D0CF11E0A1B11AE1".toCharArray()))) {
                System.out.println("File C:\\test.xls is a Excel file");
            } else {
                is = new FileInputStream(f);
                InputStreamReader isr = new InputStreamReader(is);
                BufferedReader bf = new BufferedReader(isr);
                String line = bf.readLine();
                System.out.println(line);
                is.close();
            }
        }
    }
}

Код

/**
 * @author Alexander Salnikov
 * @version 0.1
 */
 public class HexCodec {
        private final char[] kDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
                'B', 'C', 'D', 'E', 'F'};

        public char[] bytesToHex(byte[] raw) {
            int length = raw.length;
            char[] hex = new char[length * 2];
            for (int i = 0; i < length; i++) {
                int value = (raw[i] + 256) % 256;
                int highIndex = value >> 4;
                int lowIndex = value & 0x0f;
                hex[i * 2 + 0] = kDigits[highIndex];
                hex[i * 2 + 1] = kDigits[lowIndex];
            }
            return hex;
        }
    }


Google.com и 10 минут времени

Автор: _and 22.4.2009, 04:17
Цитата(LSD @  21.4.2009,  18:23 Найти цитируемый пост)
А нафига нужно поле fileType

все писалось на коленке, на работоспособность не проверпял так что звиняйте коль чего не так smile

Автор: goodday1941 22.4.2009, 10:10
далее развиваю тему с енумом...
в энум я бы добавил статический паблик метод который бы по файлнейму возвращал тип энума выглядело это бы как то так:

Код

public enum FileTypes {
    XML("xml"),
    XSL("xsl");
    private String fileType;
    FileTypes(String s) {
        this.fileType = s;
    }
    public String getFileType() {
        return fileType;
    }
    
    public static FileTypes getByFilename(String filename){
       for(FileTypes ft:values()){
          if(filename.toLowerCase().endsWith("."+ft.getFileType()) return ft;
       }
       return null;//ну или пробросить эксепшн... throw new ChtoToTamNotFoundException :)
    }
}

Автор: LSD 22.4.2009, 11:03
Цитата(Asal @  21.4.2009,  15:42 Найти цитируемый пост)
А почему никто не прислушался к Amp, человек же дело сказал!
Расширение же у файла может быть любое, и в винде, и под линем.

Потому что:
1. Это ненадежно, например Офис 2007 сменил формат документов, теперь он начинается с другой сигнатуры. А файл XML вообще не имеет четкой сигнатуры (пролог документа очень часто опускается). А что прикажете делать если надо добавить ещё один тип файлов, опять искать какая у него сигнатура?
2. Вообще-то расширения для того и придуманы, чтобы идентифицировать типы файлов. Если файл имеет неправильное расширение, это проблемы пользователя. И если у него файлы имеют неправильное расширение, то пусть озаботиться тем, чтобы вручную указать что это за файл.

Вообще это очень малораспространённая практика. Так пожалуй поступают только программы для просмотра картинок и программы для восстановления данных.

Автор: Amp 22.4.2009, 11:38
Цитата(LSD @  22.4.2009,  11:03 Найти цитируемый пост)
Вообще это очень малораспространённая практика. Так пожалуй поступают только программы для просмотра картинок и программы для восстановления данных. 

У меня так файловый менеджер работает - расширения им игнорируются smile В некоторых запущенных случаях (например форматы OpenDocument) ему приходится проверять не только сигнатуры, но даже лезть в потоки внутри zip-архива.

P.S. Я и не думал, что такую тему можно мусолить целую форумную страницу.

Автор: math64 22.4.2009, 11:43
что за endsWith() без аргумента? Нужно так:
Код

  if(filename.toLowerCase().endsWith("."+ft.getFileType()) return ft;

Автор: goodday1941 22.4.2009, 14:45
math64, сорри, ошибка моя  smile ... просто поток мысли печатал ) видимо мой мозг периодически сбоит )

Автор: #Maestro# 22.4.2009, 14:50
прошу прощения, что вмешиваюсь, но у меня новая проблемма. при создании Excel в строке
Код
 HSSFCell cell.setCellFormula(collValues.get("stroka")); 

вылетает ошибка:

Exception in thread "main" org.apache.poi.ss.formula.FormulaParser$FormulaParseException: Specified named range 'stroka' does not exist in the current workbook.

видимо setCellFormula(...)  может воспринимать только цифры. а что делать, если далжна быть строка?

и как компилятор понял, что создаваемый файл называется "workbook"? если я имя задаю только в конце кода.
кстати в NetBeanse (или как там его?) версии 5.5 такая проблема не возникает, возникает в шестом.

помогите, кто можетsmile

Автор: LSD 24.4.2009, 12:13
Модератор: Пожалуйста, один топик - один вопрос.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)