2016-12-06 2 views
4

В настоящее время я работаю над проектом Java, который должен позволить пользователю экспортировать проекты в комплекте с программным обеспечением Windows (.exe) или OS X app (.app), чтобы распространять данные на другие рабочие станции. Программное обеспечение Windows и OS X хранится как сжатый zip-файл и несжатый, если проект экспортируется. Моя проблема в том, что распаковка OS X-приложения на Windows нарушает символические ссылки внутри связанных фреймворков. Это, в свою очередь, нарушает подпись приложения и вызывает проблемы при запуске приложения в OS X.Работа с файлами символических ссылок unix на файловой системе Windows

Я использую библиотеки сжатия Apache Commons для распаковки пакетов, что позволяет мне обнаруживать символические ссылки и их цель. С OS X я могу воссоздать символическую ссылку с методами из java.nio.file.Files, но с Windows это потребует прав администратора, которые я немного не решаюсь добавить в качестве предварительного условия для использования программного обеспечения (даже если включено, я не уверен, что это сработает - не пробовал).

У меня есть небольшое понимание причины, по которой ссылки сломаны, но если я правильно понял, файловая система Windows не включает поддержку типа файла символической ссылки Unix, и, следовательно, ссылка распаковывается как обычный файл и больше не будет распознаваться как символическая ссылка при открытии на OS X.

Итак, мой вопрос заключается в том, что я могу как-то просто портировать файл символической ссылки в файловую систему Windows, сохраняя конкретные биты Unix или сохраняя эту информацию прямо невозможно? Или я должен просто изменить метод экспорта, чтобы добавить файлы проекта в существующий zip-файл, и в этом случае информация symlink, вероятно, будет сохранена до тех пор, пока zip не будет извлечен на целевой машине?

текущий код цикла по каждому ZipArchiveEntry из ZipFile, как показано ниже:

byte data[] = new byte[BUFFER]; 

Enumeration<ZipArchiveEntry> entries = zipFile.getEntries(); 

while (entries.hasMoreElements()) { 
    ZipArchiveEntry zipEntry = entries.nextElement(); 
    String destFilename = copyFolder + zipEntry.getName(); 
    File destFile = new File(destFilename); 

    if (zipEntry.isUnixSymlink()) {    
     File target = new File(zipFile.getUnixSymlink(zipEntry));    
     try { 
      // Try to create symbolic link - currently only works with OS X 
      Files.createSymbolicLink(destFile.toPath(), target.toPath()); 
      continue; 
     } catch (Exception e) { 
      System.out.println("Failed to create symbolic link: " + 
       destFile.getAbsolutePath() + " -> " + 
       target.getAbsolutePath()); 
     } 
    } 

    // If file 
    int count; 
    FileOutputStream fos = new FileOutputStream(destFile); 

    try (BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER)) { 
     InputStream is = zipFile.getInputStream(zipEntry); 
     while ((count = is.read(data, 0, BUFFER)) != -1) { 
      dest.write(data, 0, count); 
     } 
    } 
} 
+0

Не могли бы вы рассказать нам немного о рабочем процессе, в котором это используется (например, какое устройство представляет собой ZIP несжатый в Windows, и как это устройство переносится на Mac позже)? Я запутался, так как в Windows только файловая система NTFS поддерживает символические ссылки, а FAT32 этого не делает, поэтому, если вы распакуете ZIP на машине Windows на USB-ключ, если USB-ключ FAT отформатирован, символические ссылки будут потеряны. Если формат NTFS отформатирован, Mac (по умолчанию) не сможет его прочитать. Кроме того, каталоги могут быть символически привязаны любым пользователем, вам нужны только администраторы, которые используют symlink Files. – mihi

+0

Кроме того, если вы скопируете файл/символическую ссылку в проводнике Windows, копия не будет привязана к символам, независимо от задействованных файловых систем (даже если NTFS для NTFS). – mihi

+0

Текущий рабочий процесс следующий: 1) программное обеспечение для просмотра данных (OS X и версия для Windows) распаковывается до экспорта 2) экспортированные данные сохраняются рядом с программным обеспечением просмотра 3) все это снова сжимается в zip-файл и отправленных на FTP-сервер. Инструкции по загрузке пакета отправляются получателю по электронной почте И проблема: 4) Пользователь с OS X не может открыть программное обеспечение для просмотра, потому что приложение OS X сломалось во время процесса распаковки-> сжатия на окнах. – pnkkr

ответ

3

файловой системы Windows, использует подобный подход, как UNIX, чтобы определить, что символическая (подобно Аппаратно или программно ссылки), но они не на 100% совместимы. Вы можете узнать больше об этом здесь: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365680(v=vs.85).aspx Простой ответ на ваш вопрос - вы не можете просто побитовое копирование ссылок иметь одни и те же конкретные биты Unix, потому что в Windows NTFS их просто нет. JAVA также предназначен для работы в песочнице, поэтому у вас нет доступа к системному низкоуровневому API, чтобы сделать «все, что вы хотите». Я бы не пошел на такую ​​системную задачу с JAVA. Наверное, вам не придется.

Зависит от вашей роли в этом проекте, вы можете переопределить, какой пакет должен содержать. Вам действительно нужны символические ссылки внутри? Может быть, более универсально иметь какой-то «файл свойств», который объединяет разные части? Или распространять его как базу данных? Старайтесь не зависеть от конкретной реализации системы.

+0

Я считаю, что в этом случае не для меня, чтобы решить, должен ли связка содержать символические ссылки или нет - это яблочный способ делать что-то со связанными фреймами. https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/FrameworkAnatomy.html Однако, спасибо за ваш полезный ответ! :) – pnkkr

+0

Файл свойств - хорошая идея, и это нужно делать, если вы хотите, чтобы ваше приложение кросс-платформенное. Apple способ, очевидно, для Apple-only ... Вы могли бы использовать файл свойств, когда может возникнуть создание ссылки? – Matthieu

3

Для решения этой проблемы вам понадобится определенный для Windows и нестандартный (по крайней мере, для Java) подход, поскольку для его решения не существует стандартного межплатформенного Java-метода. Например, вы можете попытаться использовать Runtime.exec рядом с вызовом "mklink" utility. Команда mklink позволяет создавать жесткие и мягкие (символические) ссылки, а также создавать соединения - в основном он создает различные типы точек повторного разбора, доступных для файловой системы Windows. Если вы хотите получить доступ к собственному коду, вы также можете использовать предварительно сделанные JNA mapping to Kernel32.dll или write a custom mapping to Kernel32.dll и позвонить по WinBase.h предоставленному способу CreateSymbolicLink(LPTSTR,LPTSTR,DWORD).

1

В общем, я бы посоветовал вам избегать символических ссылок и жестких ссылок на Windows, если это возможно.

Symlinks и жесткие ссылки были введены в Windows, довольно поздно, и его поддержка довольно бедна:

  • Большинство пользователей Windows не ожидают симлинки в своей файловой системе
  • Symlinks поддерживаются только локально на NTFS, а не в других файловых системах (FAT, exFAT, UDF) или через сетевые ресурсы
  • Сторонние инструменты (Zipper, средства резервного копирования, программное обеспечение для облачной синхронизации), а также некоторое программное обеспечение Microsoft (например, история версий файлов, то есть Windows «Машина времени» или проводник Windows при копировании/перемещении папки) не может справиться с сим ссылки или жесткие ссылки, либо разрешая их, либо разбивая/отображая сообщение об ошибке).
  • Разрешения, необходимые для их создания различаются в зависимости от версии Windows (на Windows 7, обычный пользователь может создать символическую ссылку (распределительную) к каталогу, он может получить доступ, но в Windows XP вы должны права администратора в любом случае)

Поэтому, поскольку вам нужны символические ссылки только временно (как вы писали в комментариях), а затем снова застегивайте файлы снова, я бы посоветовал, что при распаковке вы создаете свои собственные файлы маркеров для обозначения символических ссылок, а позже, когда вы zipping вы конвертируете их обратно в соответствующие символические ссылки UNIX в ZIP-файлах.