public static FileResource createResource(String cwd, String pathname) { if (pathname == null) { // null pathnames do not exist return new RegularFileResource(JRubyNonExistentFile.NOT_EXIST); } // Try as a jar resource first FileResource jarResource = JarResource.create(pathname); if (jarResource != null) { return jarResource; } return new RegularFileResource(create(cwd, pathname)); }
@Override public InputStream openInputStream() throws IOException { if (!exists()) { throw new ResourceException.NotFound(absolutePath()); } if (isDirectory()) { throw new ResourceException.FileIsDirectory(absolutePath()); } return new FileInputStream(file); }
public FileTime lastAccessTime() throws IOException { return readAttributes().lastAccessTime(); }
final ModeFlags modeFlags = ModeFlags.createModeFlags(flags); if (posix.isNative() && !Platform.IS_WINDOWS) { int fd = posix.open(absolutePath(), modeFlags.getFlags(), perm); if (fd < 0) throwFromErrno(posix.errno()); posix.fcntlInt(fd, Fcntl.F_SETFD, posix.fcntl(fd, Fcntl.F_GETFD) | FcntlLibrary.FD_CLOEXEC); return new NativeDeviceChannel(fd, true); throw new ResourceException.NotFound(absolutePath()); } else if (!file.canWrite()) { throw new ResourceException.PermissionDenied(absolutePath()); } else { throw new ResourceException.FileExists(absolutePath()); Channel channel = createChannel(modeFlags); throw new ResourceException.FileIsDirectory(absolutePath()); throw new ResourceException.NotFound(absolutePath()); return createChannel(modeFlags);
@Override public FileStat stat(POSIX posix) { return posix.stat(absolutePath()); }
private Channel createChannel(ModeFlags flags) throws IOException { FileChannel fileChannel; /* Because RandomAccessFile does not provide a way to pass append * mode, we must manually seek if using RAF. FileOutputStream, * however, does properly honor append mode at the lowest levels, * reducing append write costs when we're only doing writes. * * The code here will use a FileOutputStream if we're only writing, * setting isInAppendMode to true to disable our manual seeking. * * RandomAccessFile does not handle append for us, so if we must * also be readable we pass false for isInAppendMode to indicate * we need manual seeking. */ try{ if (flags.isWritable() && !flags.isReadable()) { FileOutputStream fos = new FileOutputStream(file, flags.isAppendable()); fileChannel = fos.getChannel(); } else { RandomAccessFile raf = new RandomAccessFile(file, flags.toJavaModeString()); fileChannel = raf.getChannel(); } } catch (FileNotFoundException ex) { throw mapFileNotFoundOnGetChannel(this, ex); } return fileChannel; }
@Override public boolean exists() { if (file.exists()) { String path = filePath; if (path.length() > 1 && path.charAt(path.length() - 1) == '/') { path = file.getPathDefault(); if (path.length() > 0 && path.charAt(path.length() - 1) != '/' && !isDirectory()) { return false; } } return true; } return false; }
@Override public boolean exists() { // MRI behavior: Even broken symlinks should return true. return file.exists() || isSymLink(); }
final ModeFlags modeFlags = ModeFlags.createModeFlags(flags); if (posix.isNative() && !Platform.IS_WINDOWS) { int fd = posix.open(absolutePath(), modeFlags.getFlags(), perm); if (fd < 0) throwFromErrno(posix.errno()); posix.fcntlInt(fd, Fcntl.F_SETFD, posix.fcntl(fd, Fcntl.F_GETFD) | FcntlLibrary.FD_CLOEXEC); return new NativeDeviceChannel(fd, true); throw new ResourceException.NotFound(absolutePath()); } else if (!file.canWrite()) { throw new ResourceException.PermissionDenied(absolutePath()); } else { throw new ResourceException.FileExists(absolutePath()); Channel channel = createChannel(modeFlags); throw new ResourceException.FileIsDirectory(absolutePath()); throw new ResourceException.NotFound(absolutePath()); return createChannel(modeFlags);
@Override public FileStat lstat(POSIX posix) { return posix.lstat(absolutePath()); }
private Channel createChannel(ModeFlags flags) throws IOException { FileChannel fileChannel; /* Because RandomAccessFile does not provide a way to pass append * mode, we must manually seek if using RAF. FileOutputStream, * however, does properly honor append mode at the lowest levels, * reducing append write costs when we're only doing writes. * * The code here will use a FileOutputStream if we're only writing, * setting isInAppendMode to true to disable our manual seeking. * * RandomAccessFile does not handle append for us, so if we must * also be readable we pass false for isInAppendMode to indicate * we need manual seeking. */ try{ if (flags.isWritable() && !flags.isReadable()) { FileOutputStream fos = new FileOutputStream(file, flags.isAppendable()); fileChannel = fos.getChannel(); } else { RandomAccessFile raf = new RandomAccessFile(file, flags.toJavaModeString()); fileChannel = raf.getChannel(); } } catch (FileNotFoundException ex) { throw mapFileNotFoundOnGetChannel(this, ex); } return fileChannel; }
@Override public boolean exists() { if (file.exists()) { String path = filePath; if (path.length() > 1 && path.charAt(path.length() - 1) == '/') { path = file.getPathDefault(); if (path.length() > 0 && path.charAt(path.length() - 1) != '/' && !isDirectory()) { return false; } } return true; } return false; }
@Override public InputStream openInputStream() throws IOException { if (!exists()) { throw new ResourceException.NotFound(absolutePath()); } if (isDirectory()) { throw new ResourceException.FileIsDirectory(absolutePath()); } return new FileInputStream(file); }
static FileResource wrap(POSIX posix, JRubyFile file) { return new RegularFileResource(posix, file, file.getPathDefault()); }
private void throwFromErrno(final int err) throws IOException { Errno errno = Errno.valueOf(err); switch (errno) { case EACCES: throw new ResourceException.PermissionDenied(absolutePath()); case EEXIST: throw new ResourceException.FileExists(absolutePath()); case EINVAL: throw new ResourceException.InvalidArguments(absolutePath()); case ENOENT: throw new ResourceException.NotFound(absolutePath()); case ELOOP: throw new ResourceException.TooManySymlinks(absolutePath()); case EISDIR: throw new ResourceException.FileIsDirectory(absolutePath()); case ENOTDIR: throw new ResourceException.FileIsNotDirectory(absolutePath()); case EMFILE: default: throw new InternalIOException(errno.description()); } }
public FileTime creationTime() throws IOException { return readAttributes().creationTime(); }
private Channel createChannel(ModeFlags flags) throws IOException { SeekableByteChannel fileChannel; try{ if (flags.isWritable() && !flags.isReadable()) { FileOutputStream fos = new FileOutputStream(file, flags.isAppendable()); fileChannel = fos.getChannel(); } else { RandomAccessFile raf = new RandomAccessFile(file, flags.toJavaModeString()); fileChannel = raf.getChannel(); // O_APPEND specifies that all writes will always be at the end of the open file // (even if we happened to have seek'd away from the end of the file o_O). RAF // does not have these semantics so we wrap it to support this unusual case. if (flags.isAppendable()) fileChannel = new AppendModeChannel((FileChannel) fileChannel); } } catch (FileNotFoundException ex) { throw mapFileNotFoundOnGetChannel(this, ex); } try { if (flags.isTruncate()) fileChannel.truncate(0); } catch (IOException ioe) { // ignore; it's a pipe or fifo that can't be truncated (we only care about illegal seek). if (!"Illegal seek".equals(ioe.getMessage())) throw ioe; } return fileChannel; }
static FileResource wrap(POSIX posix, JRubyFile file) { return new RegularFileResource(posix, file, file.getPathDefault()); }
@Override public boolean isSymLink() { try { return symlinkPosix.lstat(absolutePath()).isSymlink(); } catch (Throwable t) { return false; } }
public FileTime creationTime() throws IOException { return readAttributes().creationTime(); }