| |||
| [Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] |
|
All, Prior to 1.5, we have been able to "open" a file with extended characters by performing something of the order: File aFile = new File("HelloÇüéâäà.txt"); String[] args = new String[] { "open", aFile.getAbsolutePath()}; Process aProcess = Runtime.getRuntime().exec(args); ... We did run into a problem with the above on mounted AFP volumes and the workaround was to manually decompose extended characters for the open to work. This is an annoying bug, however, it could be worked around by performing the following instead: File aFile = new File("HelloC\u0327u\u0308e\u0301a\u0302a\u0308a\u0300.txt"); String[] args = new String[] { "open", aFile.getAbsolutePath()}; Process aProcess = Runtime.getRuntime().exec(args); ... As I stated, this worked wonderfully, until we got to 1.5. Starting in 1.5, either of the two examples above will fail stating (via the error output stream and with non-printable characters replaced with ?'s): "...No such file: /Users/mmacaluso/Java/test/Hello?C?u?e?a?a?a.txt After investigating what the open command receives as the parameter, it appears that the 1.5 VM has reverted from the UTF-8 (in < 1.5) encoding to the MacRoman encoding. This is the reason that the "open" command will fail because most other command line applications assume UTF-8 for their command line parameters. This is re-creatable on every OS X machine that it is tried. We have tried to workaround this bug within JAVA, but we were stymied in almost every case. We even tried the ProcessBuilder class that is specific to 1.5, but it exhibits the same symptoms. As a last ditch effort, we now write a temporary script file written in UTF-8 that will perform the "open" command as we would expect. This is very ugly because we then have to exec a chmod command, execute the script and then delete the file. Extra work, but at least the functionality is there. To summarize, there are two bugs: 1) Radar: 4486240. Extended characters on remote AFP volumes REQUIRE the canonically decomposed UTF-8 form in order to obtain a valid File instance. The canonically decomposed UTF-8 form will work with local file, so APPLE should consider using this form ALWAYS when dropping down to the file system objects. 2) Radar: 4486195. On 1.5 the default encoding when doing an "exec" has reverted to MacRoman instead of the previous UTF-8. This has crippled the use of runtime.exec when extended characters are in use. Below is an example file that exhibits the behavior of 2). If run on a Mounted Volume (may have to be run multiple times), then 1) is exhibited as well. Regards, Michael /****************************** Clip Here *********************************/ import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; public class ExtendedCharacterTests { /** * @param args */ public static void main(String[] args) { // "HelloÇüéâäà.txt" // this should work on system/local volumes in <= 1.4.2 OpenFile("Hello\u00C7\u00FC\u00E9\u00E2\u00E4\u00E0.txt"); // Decomposed "HelloÇüéâäà.txt" // this should work on system/local volumes AND remote AFP volumes in <= 1.4.2 OpenFile("HelloC\u0327u\u0308e\u0301a\u0302a\u0308a\u0300.txt"); } public static void OpenFile(String aName) { File aFile = new File(aName); System.out.println("File "+ aFile.getAbsolutePath() + " exists: " + aFile.exists()); if (!aFile.exists()) { FileOutputStream aFileOutputStream = null; try { aFileOutputStream = new FileOutputStream(aFile); PrintWriter aPrintWriter = new PrintWriter(new OutputStreamWriter(aFileOutputStream), true); aPrintWriter.print("Attempting to open '"); aPrintWriter.print(aName); aPrintWriter.println("'"); } catch (Exception e) { e.printStackTrace(); } finally { if (null != aFileOutputStream) try { aFileOutputStream.close(); } catch (Exception e) {} } } String execArgs[] = new String[] {"open", aFile.getAbsolutePath()}; byte[] aByteBuffer = new byte[32768]; { Process aProcess = null; try { aProcess = Runtime.getRuntime().exec(execArgs); aProcess.waitFor(); InputStream anInputStream = aProcess.getErrorStream(); int aSize = anInputStream.read(aByteBuffer); if (aSize > 0) { String anErrorString = new String(aByteBuffer, 0, aSize); System.err.println(anErrorString); } } catch (Exception e) { e.printStackTrace(); } int returnCode = aProcess.exitValue(); System.out.println("Exit code from exec: " + returnCode); } } } /****************************** Clip Here *********************************/ |
_______________________________________________ Do not post admin requests to the list. They will be ignored. Java-dev mailing list (email@hidden) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/java-dev/email@hidden This email sent to email@hidden
| Home | Archives | FAQ | Terms/Conditions | Contact | RSS | Lists | About |
Visit the Apple Store online or at retail locations.
1-800-MY-APPLE
Contact Apple | Terms of Use | Privacy Policy
Copyright © 2007 Apple Inc. All rights reserved.