/** * ‘file.append’ attempts to append the files named by its second argument to those named by its * first. The R subscript recycling rule is used to align names given in vectors of different * lengths. */ @Internal("file.append") @DataParallel public static boolean fileAppend( @Current Context context, String destFileName, String sourceFileName) { try { FileObject sourceFile = context.resolveFile(sourceFileName); if (!sourceFile.exists()) { return false; } FileObject destFile = context.resolveFile(destFileName); OutputStream out = destFile.getContent().getOutputStream(true); try { InputStream in = sourceFile.getContent().getInputStream(); try { ByteStreams.copy(in, out); } finally { try { in.close(); } catch (Exception ignored) { } } } finally { try { out.close(); } catch (Exception ignored) { } } return true; } catch (Exception e) { return false; } }
/** * Utility function to extract information about files on the user's file systems. * * @param context current call Context * @param paths the list of files for which to return information * @return list column-oriented table of file information * @throws FileSystemException */ @Internal("file.info") public static ListVector fileInfo(@Current Context context, StringVector paths) throws FileSystemException { DoubleArrayVector.Builder size = new DoubleArrayVector.Builder(); LogicalArrayVector.Builder isdir = new LogicalArrayVector.Builder(); IntArrayVector.Builder mode = (IntArrayVector.Builder) new IntArrayVector.Builder() .setAttribute(Symbols.CLASS, StringVector.valueOf("octmode")); DoubleArrayVector.Builder mtime = new DoubleArrayVector.Builder(); StringVector.Builder exe = new StringVector.Builder(); for (String path : paths) { if (StringVector.isNA(path)) { throw new EvalException("invalid filename argument"); } FileObject file = context.resolveFile(path); if (file.exists()) { if (file.getType() == FileType.FILE) { size.add((int) file.getContent().getSize()); } else { size.add(0); } isdir.add(file.getType() == FileType.FOLDER); mode.add(mode(file)); try { mtime.add(file.getContent().getLastModifiedTime()); } catch (Exception e) { mtime.add(0); } exe.add(file.getName().getBaseName().endsWith(".exe") ? "yes" : "no"); } else { size.addNA(); isdir.addNA(); mode.addNA(); mtime.addNA(); exe.addNA(); } } return ListVector.newNamedBuilder() .add("size", size) .add("isdir", isdir) .add("mode", mode) .add("mtime", mtime) .add("ctime", mtime) .add("atime", mtime) .add("exe", exe) .build(); }
@Internal("file.create") @DataParallel public static boolean fileCreate( @Current Context context, @Recycle String fileName, @Recycle(false) boolean showWarnings) throws IOException { try { FileObject file = context.resolveFile(fileName); // VFS will create the parent folder if it doesn't exist, // which the R method is not supposed to do if (!file.getParent().exists()) { throw new IOException("No such file or directory"); } file.getContent().getOutputStream().close(); return true; } catch (Exception e) { if (showWarnings) { Warning.invokeWarning( context, "cannot create file '%s', reason '%s'", fileName, e.getMessage()); } return false; } }
/** Helper function to extract a zip entry to the given folder. */ private static void unzipExtract( ZipInputStream zin, ZipEntry entry, FileObject exdir, boolean junkpaths, boolean overwrite) throws IOException { if (junkpaths) { throw new EvalException("unzip(junpaths=false) not yet implemented"); } FileObject exfile = exdir.resolveFile(entry.getName()); if (exfile.exists() && !overwrite) { throw new EvalException( "file to be extracted '%s' already exists", exfile.getName().getURI()); } OutputStream out = exfile.getContent().getOutputStream(); try { byte buffer[] = new byte[64 * 1024]; int bytesRead; while ((bytesRead = zin.read(buffer)) != -1) { out.write(buffer, 0, bytesRead); } } finally { out.close(); } }