1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.appender;
18
19 import java.io.BufferedOutputStream;
20 import java.io.File;
21 import java.io.FileNotFoundException;
22 import java.io.FileOutputStream;
23 import java.io.IOException;
24 import java.io.OutputStream;
25 import java.nio.channels.FileChannel;
26 import java.nio.channels.FileLock;
27
28
29
30
31
32 public class FileManager extends OutputStreamManager {
33
34 private static final FileManagerFactory factory = new FileManagerFactory();
35
36 private final boolean isAppend;
37 private final boolean isLocking;
38
39 protected FileManager(String fileName, OutputStream os, boolean append, boolean locking) {
40 super(os, fileName);
41 this.isAppend = append;
42 this.isLocking = locking;
43 }
44
45
46
47
48
49
50
51
52
53 public static FileManager getFileManager(String fileName, boolean append, boolean locking, boolean bufferedIO) {
54
55 if (locking && bufferedIO) {
56 locking = false;
57 }
58 return (FileManager) getManager(fileName, new FactoryData(append, locking, bufferedIO), factory);
59 }
60
61 @Override
62 protected synchronized void write(byte[] bytes, int offset, int length) {
63
64 if (isLocking) {
65 FileChannel channel = ((FileOutputStream) getOutputStream()).getChannel();
66 try {
67
68
69
70
71
72
73
74 FileLock lock = channel.lock(0, Long.MAX_VALUE, false);
75 try {
76 super.write(bytes, offset, length);
77 } finally {
78 lock.release();
79 }
80 } catch (IOException ex) {
81 throw new AppenderRuntimeException("Unable to obtain lock on " + getName(), ex);
82 }
83
84 } else {
85 super.write(bytes, offset, length);
86 }
87 }
88
89
90
91
92
93 public String getFileName() {
94 return getName();
95 }
96
97
98
99
100
101 public boolean isAppend() {
102 return isAppend;
103 }
104
105
106
107
108
109 public boolean isLocking() {
110 return isLocking;
111 }
112
113
114
115
116 private static class FactoryData {
117 private final boolean append;
118 private final boolean locking;
119 private final boolean bufferedIO;
120
121
122
123
124
125
126
127 public FactoryData(boolean append, boolean locking, boolean bufferedIO) {
128 this.append = append;
129 this.locking = locking;
130 this.bufferedIO = bufferedIO;
131 }
132 }
133
134
135
136
137 private static class FileManagerFactory implements ManagerFactory<FileManager, FactoryData> {
138
139
140
141
142
143
144
145 public FileManager createManager(String name, FactoryData data) {
146 File file = new File(name);
147 final File parent = file.getParentFile();
148 if (null != parent && !parent.exists()) {
149 parent.mkdirs();
150 }
151
152 OutputStream os;
153 try {
154 os = new FileOutputStream(name, data.append);
155 if (data.bufferedIO) {
156 os = new BufferedOutputStream(os);
157 }
158 return new FileManager(name, os, data.append, data.locking);
159 } catch (FileNotFoundException ex) {
160 LOGGER.error("FileManager (" + name + ") " + ex);
161 }
162 return null;
163 }
164 }
165
166 }